diff --git a/.devcontainer/webxr-javascript-workshop/devcontainer.json b/.devcontainer/webxr-javascript-workshop/devcontainer.json index 244d62a7..39bea66c 100644 --- a/.devcontainer/webxr-javascript-workshop/devcontainer.json +++ b/.devcontainer/webxr-javascript-workshop/devcontainer.json @@ -56,7 +56,8 @@ "README.md": true, "public": true, "download-toolbar.js": true - } + }, + "terminal.integrated.cwd": "${workspaceFolder}/project" } }, "codespaces": { diff --git a/sources/webxr-javascript-workshop/.astro/data-store.json b/sources/webxr-javascript-workshop/.astro/data-store.json index 44ef02d8..d27e64c4 100644 --- a/sources/webxr-javascript-workshop/.astro/data-store.json +++ b/sources/webxr-javascript-workshop/.astro/data-store.json @@ -1 +1 @@ -[["Map",1,2,9,10],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.18.1","content-config-digest","a30a942a2ceda2e1","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"where\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true,\"allowedHosts\":[]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[],\"remotePatterns\":[],\"responsiveStyles\":false},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":false,\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[null,null,null],\"rehypePlugins\":[[null,{\"experimentalHeadingIdCompat\":false}],null,[null,{\"themes\":[{\"name\":\"Night Owl No Italics\",\"type\":\"dark\",\"colors\":{\"focusBorder\":\"#122d42\",\"foreground\":\"#d6deeb\",\"disabledForeground\":\"#cccccc80\",\"descriptionForeground\":\"#d6deebb3\",\"errorForeground\":\"#ef5350\",\"icon.foreground\":\"#c5c5c5\",\"contrastActiveBorder\":null,\"contrastBorder\":\"#122d42\",\"textBlockQuote.background\":\"#7f7f7f1a\",\"textBlockQuote.border\":\"#007acc80\",\"textCodeBlock.background\":\"#4f4f4f\",\"textLink.activeForeground\":\"#3794ff\",\"textLink.foreground\":\"#3794ff\",\"textPreformat.foreground\":\"#d7ba7d\",\"textSeparator.foreground\":\"#ffffff2e\",\"editor.background\":\"#23262f\",\"editor.foreground\":\"#d6deeb\",\"editorLineNumber.foreground\":\"#4b6479\",\"editorLineNumber.activeForeground\":\"#c5e4fd\",\"editorActiveLineNumber.foreground\":\"#c6c6c6\",\"editor.selectionBackground\":\"#1d3b53\",\"editor.inactiveSelectionBackground\":\"#7e57c25a\",\"editor.selectionHighlightBackground\":\"#5f7e9779\",\"editorError.foreground\":\"#ef5350\",\"editorWarning.foreground\":\"#b39554\",\"editorInfo.foreground\":\"#3794ff\",\"editorHint.foreground\":\"#eeeeeeb2\",\"problemsErrorIcon.foreground\":\"#ef5350\",\"problemsWarningIcon.foreground\":\"#b39554\",\"problemsInfoIcon.foreground\":\"#3794ff\",\"editor.findMatchBackground\":\"#5f7e9779\",\"editor.findMatchHighlightBackground\":\"#1085bb5d\",\"editor.findRangeHighlightBackground\":\"#3a3d4166\",\"editorLink.activeForeground\":\"#4e94ce\",\"editorLightBulb.foreground\":\"#ffcc00\",\"editorLightBulbAutoFix.foreground\":\"#75beff\",\"diffEditor.insertedTextBackground\":\"#99b76d23\",\"diffEditor.insertedTextBorder\":\"#c5e47833\",\"diffEditor.removedTextBackground\":\"#ef535033\",\"diffEditor.removedTextBorder\":\"#ef53504d\",\"diffEditor.insertedLineBackground\":\"#9bb95533\",\"diffEditor.removedLineBackground\":\"#ff000033\",\"editorStickyScroll.background\":\"#011627\",\"editorStickyScrollHover.background\":\"#2a2d2e\",\"editorInlayHint.background\":\"#5f7e97cc\",\"editorInlayHint.foreground\":\"#ffffff\",\"editorInlayHint.typeBackground\":\"#5f7e97cc\",\"editorInlayHint.typeForeground\":\"#ffffff\",\"editorInlayHint.parameterBackground\":\"#5f7e97cc\",\"editorInlayHint.parameterForeground\":\"#ffffff\",\"editorPane.background\":\"#011627\",\"editorGroup.emptyBackground\":\"#011627\",\"editorGroup.focusedEmptyBorder\":null,\"editorGroupHeader.tabsBackground\":\"var(--sl-color-black)\",\"editorGroupHeader.tabsBorder\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"editorGroupHeader.noTabsBackground\":\"#011627\",\"editorGroupHeader.border\":null,\"editorGroup.border\":\"#011627\",\"editorGroup.dropBackground\":\"#7e57c273\",\"editorGroup.dropIntoPromptForeground\":\"#d6deeb\",\"editorGroup.dropIntoPromptBackground\":\"#021320\",\"editorGroup.dropIntoPromptBorder\":null,\"sideBySideEditor.horizontalBorder\":\"#011627\",\"sideBySideEditor.verticalBorder\":\"#011627\",\"scrollbar.shadow\":\"#010b14\",\"scrollbarSlider.background\":\"#ffffff17\",\"scrollbarSlider.hoverBackground\":\"#ffffff40\",\"scrollbarSlider.activeBackground\":\"#084d8180\",\"panel.background\":\"#011627\",\"panel.border\":\"#5f7e97\",\"panelTitle.activeBorder\":\"#5f7e97\",\"panelTitle.activeForeground\":\"#ffffffcc\",\"panelTitle.inactiveForeground\":\"#d6deeb80\",\"panelSectionHeader.background\":\"#80808051\",\"terminal.background\":\"#011627\",\"widget.shadow\":\"#011627\",\"editorWidget.background\":\"#021320\",\"editorWidget.foreground\":\"#d6deeb\",\"editorWidget.border\":\"#5f7e97\",\"quickInput.background\":\"#021320\",\"quickInput.foreground\":\"#d6deeb\",\"quickInputTitle.background\":\"#ffffff1a\",\"pickerGroup.foreground\":\"#d1aaff\",\"pickerGroup.border\":\"#011627\",\"editor.hoverHighlightBackground\":\"#7e57c25a\",\"editorHoverWidget.background\":\"#011627\",\"editorHoverWidget.foreground\":\"#d6deeb\",\"editorHoverWidget.border\":\"#5f7e97\",\"editorHoverWidget.statusBarBackground\":\"#011a2f\",\"titleBar.activeBackground\":\"var(--sl-color-black)\",\"titleBar.activeForeground\":\"var(--sl-color-text)\",\"titleBar.inactiveBackground\":\"#010e1a\",\"titleBar.inactiveForeground\":\"#eeefff99\",\"titleBar.border\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"toolbar.hoverBackground\":\"#5a5d5e50\",\"toolbar.activeBackground\":\"#63666750\",\"tab.activeBackground\":\"#0b2942\",\"tab.unfocusedActiveBackground\":\"#0b2942\",\"tab.inactiveBackground\":\"#01111d\",\"tab.unfocusedInactiveBackground\":\"#01111d\",\"tab.activeForeground\":\"var(--sl-color-text)\",\"tab.inactiveForeground\":\"#5f7e97\",\"tab.unfocusedActiveForeground\":\"#5f7e97\",\"tab.unfocusedInactiveForeground\":\"#5f7e97\",\"tab.hoverBackground\":null,\"tab.unfocusedHoverBackground\":null,\"tab.hoverForeground\":null,\"tab.unfocusedHoverForeground\":null,\"tab.border\":\"#272b3b\",\"tab.lastPinnedBorder\":\"#585858\",\"tab.activeBorder\":\"transparent\",\"tab.unfocusedActiveBorder\":\"#262a39\",\"tab.activeBorderTop\":\"var(--sl-color-accent-high)\",\"tab.unfocusedActiveBorderTop\":null,\"tab.hoverBorder\":null,\"tab.unfocusedHoverBorder\":null,\"tab.activeModifiedBorder\":\"#3399cc\",\"tab.inactiveModifiedBorder\":\"#3399cc80\",\"tab.unfocusedActiveModifiedBorder\":\"#3399cc80\",\"tab.unfocusedInactiveModifiedBorder\":\"#3399cc40\",\"badge.background\":\"#5f7e97\",\"badge.foreground\":\"#ffffff\",\"button.background\":\"#7e57c2cc\",\"button.foreground\":\"#ffffffcc\",\"button.border\":\"#122d42\",\"button.separator\":\"#ffffff52\",\"button.hoverBackground\":\"#7e57c2\",\"button.secondaryBackground\":\"#3a3d41\",\"button.secondaryForeground\":\"#ffffff\",\"button.secondaryHoverBackground\":\"#46494e\",\"dropdown.background\":\"#011627\",\"dropdown.foreground\":\"#ffffffcc\",\"dropdown.border\":\"#5f7e97\",\"list.activeSelectionBackground\":\"#234d708c\",\"list.activeSelectionForeground\":\"#ffffff\",\"tree.indentGuidesStroke\":\"#585858\",\"input.background\":\"#0b253a\",\"input.foreground\":\"#ffffffcc\",\"input.placeholderForeground\":\"#5f7e97\",\"inputOption.activeBorder\":\"#ffffffcc\",\"inputOption.hoverBackground\":\"#5a5d5e80\",\"inputOption.activeBackground\":\"#122d4266\",\"inputOption.activeForeground\":\"#ffffff\",\"inputValidation.infoBackground\":\"#00589ef2\",\"inputValidation.infoBorder\":\"#64b5f6\",\"inputValidation.warningBackground\":\"#675700f2\",\"inputValidation.warningBorder\":\"#ffca28\",\"inputValidation.errorBackground\":\"#ab0300f2\",\"inputValidation.errorBorder\":\"#ef5350\",\"keybindingLabel.background\":\"#8080802b\",\"keybindingLabel.foreground\":\"#cccccc\",\"keybindingLabel.border\":\"#33333399\",\"keybindingLabel.bottomBorder\":\"#44444499\",\"menu.foreground\":\"#ffffffcc\",\"menu.background\":\"#011627\",\"menu.selectionForeground\":\"#ffffff\",\"menu.selectionBackground\":\"#234d708c\",\"menu.separatorBackground\":\"#606060\",\"editor.snippetTabstopHighlightBackground\":\"#7c7c74c\",\"editor.snippetFinalTabstopHighlightBorder\":\"#525252\",\"terminal.ansiBlack\":\"#011627\",\"terminal.ansiRed\":\"#ef5350\",\"terminal.ansiGreen\":\"#22da6e\",\"terminal.ansiYellow\":\"#c5e478\",\"terminal.ansiBlue\":\"#82aaff\",\"terminal.ansiMagenta\":\"#c792ea\",\"terminal.ansiCyan\":\"#21c7a8\",\"terminal.ansiWhite\":\"#ffffff\",\"terminal.ansiBrightBlack\":\"#575656\",\"terminal.ansiBrightRed\":\"#ef5350\",\"terminal.ansiBrightGreen\":\"#22da6e\",\"terminal.ansiBrightYellow\":\"#ffeb95\",\"terminal.ansiBrightBlue\":\"#82aaff\",\"terminal.ansiBrightMagenta\":\"#c792ea\",\"terminal.ansiBrightCyan\":\"#7fdbca\",\"terminal.ansiBrightWhite\":\"#ffffff\",\"selection.background\":\"#4373c2\",\"input.border\":\"#5f7e97\",\"punctuation.definition.generic.begin.html\":\"#ef5350f2\",\"progress.background\":\"#7e57c2\",\"breadcrumb.foreground\":\"#a599e9\",\"breadcrumb.focusForeground\":\"#ffffff\",\"breadcrumb.activeSelectionForeground\":\"#ffffff\",\"breadcrumbPicker.background\":\"#001122\",\"list.invalidItemForeground\":\"#975f94\",\"list.dropBackground\":\"#011627\",\"list.focusBackground\":\"#010d18\",\"list.focusForeground\":\"#ffffff\",\"list.highlightForeground\":\"#ffffff\",\"list.hoverBackground\":\"#011627\",\"list.hoverForeground\":\"#ffffff\",\"list.inactiveSelectionBackground\":\"#0e293f\",\"list.inactiveSelectionForeground\":\"#5f7e97\",\"activityBar.background\":\"#011627\",\"activityBar.dropBackground\":\"#5f7e97\",\"activityBar.foreground\":\"#5f7e97\",\"activityBar.border\":\"#011627\",\"activityBarBadge.background\":\"#44596b\",\"activityBarBadge.foreground\":\"#ffffff\",\"sideBar.background\":\"#011627\",\"sideBar.foreground\":\"#89a4bb\",\"sideBar.border\":\"#011627\",\"sideBarTitle.foreground\":\"#5f7e97\",\"sideBarSectionHeader.background\":\"#011627\",\"sideBarSectionHeader.foreground\":\"#5f7e97\",\"editorCursor.foreground\":\"#80a4c2\",\"editor.wordHighlightBackground\":\"#f6bbe533\",\"editor.wordHighlightStrongBackground\":\"#e2a2f433\",\"editor.lineHighlightBackground\":\"#0003\",\"editor.rangeHighlightBackground\":\"#7e57c25a\",\"editorIndentGuide.background\":\"#5e81ce52\",\"editorIndentGuide.activeBackground\":\"#7e97ac\",\"editorRuler.foreground\":\"#5e81ce52\",\"editorCodeLens.foreground\":\"#5e82ceb4\",\"editorBracketMatch.background\":\"#5f7e974d\",\"editorOverviewRuler.currentContentForeground\":\"#7e57c2\",\"editorOverviewRuler.incomingContentForeground\":\"#7e57c2\",\"editorOverviewRuler.commonContentForeground\":\"#7e57c2\",\"editorGutter.background\":\"#011627\",\"editorGutter.modifiedBackground\":\"#e2b93d\",\"editorGutter.addedBackground\":\"#9ccc65\",\"editorGutter.deletedBackground\":\"#ef5350\",\"editorSuggestWidget.background\":\"#2c3043\",\"editorSuggestWidget.border\":\"#2b2f40\",\"editorSuggestWidget.foreground\":\"#d6deeb\",\"editorSuggestWidget.highlightForeground\":\"#ffffff\",\"editorSuggestWidget.selectedBackground\":\"#5f7e97\",\"debugExceptionWidget.background\":\"#011627\",\"debugExceptionWidget.border\":\"#5f7e97\",\"editorMarkerNavigation.background\":\"#0b2942\",\"editorMarkerNavigationError.background\":\"#ef5350\",\"editorMarkerNavigationWarning.background\":\"#ffca28\",\"peekView.border\":\"#5f7e97\",\"peekViewEditor.background\":\"#011627\",\"peekViewEditor.matchHighlightBackground\":\"#7e57c25a\",\"peekViewResult.background\":\"#011627\",\"peekViewResult.fileForeground\":\"#5f7e97\",\"peekViewResult.lineForeground\":\"#5f7e97\",\"peekViewResult.matchHighlightBackground\":\"#ffffffcc\",\"peekViewResult.selectionBackground\":\"#2e3250\",\"peekViewResult.selectionForeground\":\"#5f7e97\",\"peekViewTitle.background\":\"#011627\",\"peekViewTitleDescription.foreground\":\"#697098\",\"peekViewTitleLabel.foreground\":\"#5f7e97\",\"merge.currentHeaderBackground\":\"#5f7e97\",\"merge.incomingHeaderBackground\":\"#7e57c25a\",\"statusBar.background\":\"#011627\",\"statusBar.foreground\":\"#5f7e97\",\"statusBar.border\":\"#262a39\",\"statusBar.debuggingBackground\":\"#202431\",\"statusBar.debuggingBorder\":\"#1f2330\",\"statusBar.noFolderBackground\":\"#011627\",\"statusBar.noFolderBorder\":\"#25293a\",\"statusBarItem.activeBackground\":\"#202431\",\"statusBarItem.hoverBackground\":\"#202431\",\"statusBarItem.prominentBackground\":\"#202431\",\"statusBarItem.prominentHoverBackground\":\"#202431\",\"notifications.background\":\"#01111d\",\"notifications.border\":\"#262a39\",\"notificationCenter.border\":\"#262a39\",\"notificationToast.border\":\"#262a39\",\"notifications.foreground\":\"#ffffffcc\",\"notificationLink.foreground\":\"#80cbc4\",\"extensionButton.prominentForeground\":\"#ffffffcc\",\"extensionButton.prominentBackground\":\"#7e57c2cc\",\"extensionButton.prominentHoverBackground\":\"#7e57c2\",\"terminal.selectionBackground\":\"#1b90dd4d\",\"terminalCursor.background\":\"#234d70\",\"debugToolBar.background\":\"#011627\",\"welcomePage.buttonBackground\":\"#011627\",\"welcomePage.buttonHoverBackground\":\"#011627\",\"walkThrough.embeddedEditorBackground\":\"#011627\",\"gitDecoration.modifiedResourceForeground\":\"#a2bffc\",\"gitDecoration.deletedResourceForeground\":\"#ef535090\",\"gitDecoration.untrackedResourceForeground\":\"#c5e478ff\",\"gitDecoration.ignoredResourceForeground\":\"#395a75\",\"gitDecoration.conflictingResourceForeground\":\"#ffeb95cc\",\"source.elm\":\"#5f7e97\",\"string.quoted.single.js\":\"#ffffff\",\"meta.objectliteral.js\":\"#82aaff\"},\"fg\":\"#d6deeb\",\"bg\":\"#23262f\",\"semanticHighlighting\":false,\"settings\":[{\"name\":\"Changed\",\"scope\":[\"markup.changed\",\"meta.diff.header.git\",\"meta.diff.header.from-file\",\"meta.diff.header.to-file\"],\"settings\":{\"foreground\":\"#a2bffc\"}},{\"name\":\"Deleted\",\"scope\":[\"markup.deleted.diff\"],\"settings\":{\"foreground\":\"#f27775fe\"}},{\"name\":\"Inserted\",\"scope\":[\"markup.inserted.diff\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Global settings\",\"settings\":{\"background\":\"#011627\",\"foreground\":\"#d6deeb\"}},{\"name\":\"Comment\",\"scope\":[\"comment\"],\"settings\":{\"foreground\":\"#919f9f\",\"fontStyle\":\"\"}},{\"name\":\"String\",\"scope\":[\"string\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"String Quoted\",\"scope\":[\"string.quoted\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"Support Constant Math\",\"scope\":[\"support.constant.math\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Number\",\"scope\":[\"constant.numeric\",\"constant.character.numeric\"],\"settings\":{\"foreground\":\"#f78c6c\",\"fontStyle\":\"\"}},{\"name\":\"Built-in constant\",\"scope\":[\"constant.language\",\"punctuation.definition.constant\",\"variable.other.constant\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"User-defined constant\",\"scope\":[\"constant.character\",\"constant.other\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Constant Character Escape\",\"scope\":[\"constant.character.escape\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"RegExp String\",\"scope\":[\"string.regexp\",\"string.regexp keyword.other\"],\"settings\":{\"foreground\":\"#5ca7e4\"}},{\"name\":\"Comma in functions\",\"scope\":[\"meta.function punctuation.separator.comma\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"Variable\",\"scope\":[\"variable\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Keyword\",\"scope\":[\"punctuation.accessor\",\"keyword\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Storage\",\"scope\":[\"storage\",\"meta.var.expr\",\"meta.class meta.method.declaration meta.var.expr storage.type.js\",\"storage.type.property.js\",\"storage.type.property.ts\",\"storage.type.property.tsx\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type.function.arrow.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Class name\",\"scope\":[\"entity.name.class\",\"meta.class entity.name.type.class\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Inherited class\",\"scope\":[\"entity.other.inherited-class\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Function name\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Meta Tag\",\"scope\":[\"punctuation.definition.tag\",\"meta.tag\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"HTML Tag names\",\"scope\":[\"entity.name.tag\",\"meta.tag.other.html\",\"meta.tag.other.js\",\"meta.tag.other.tsx\",\"entity.name.tag.tsx\",\"entity.name.tag.js\",\"entity.name.tag\",\"meta.tag.js\",\"meta.tag.tsx\",\"meta.tag.html\"],\"settings\":{\"foreground\":\"#caece6\",\"fontStyle\":\"\"}},{\"name\":\"Tag attribute\",\"scope\":[\"entity.other.attribute-name\"],\"settings\":{\"fontStyle\":\"\",\"foreground\":\"#c5e478\"}},{\"name\":\"Entity Name Tag Custom\",\"scope\":[\"entity.name.tag.custom\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Library (function & constant)\",\"scope\":[\"support.function\",\"support.constant\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Support Constant Property Value meta\",\"scope\":[\"support.constant.meta.property-value\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Library class/type\",\"scope\":[\"support.type\",\"support.class\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Support Variable DOM\",\"scope\":[\"support.variable.dom\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Invalid\",\"scope\":[\"invalid\"],\"settings\":{\"background\":\"#ff2c83\",\"foreground\":\"#ffffff\"}},{\"name\":\"Invalid deprecated\",\"scope\":[\"invalid.deprecated\"],\"settings\":{\"foreground\":\"#ffffff\",\"background\":\"#d3423e\"}},{\"name\":\"Keyword Operator\",\"scope\":[\"keyword.operator\"],\"settings\":{\"foreground\":\"#7fdbca\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Relational\",\"scope\":[\"keyword.operator.relational\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Assignment\",\"scope\":[\"keyword.operator.assignment\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Arithmetic\",\"scope\":[\"keyword.operator.arithmetic\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Bitwise\",\"scope\":[\"keyword.operator.bitwise\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Increment\",\"scope\":[\"keyword.operator.increment\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Ternary\",\"scope\":[\"keyword.operator.ternary\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Double-Slashed Comment\",\"scope\":[\"comment.line.double-slash\"],\"settings\":{\"foreground\":\"#919f9f\"}},{\"name\":\"Object\",\"scope\":[\"object\"],\"settings\":{\"foreground\":\"#cdebf7\"}},{\"name\":\"Null\",\"scope\":[\"constant.language.null\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Meta Brace\",\"scope\":[\"meta.brace\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Meta Delimiter Period\",\"scope\":[\"meta.delimiter.period\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Punctuation Definition String\",\"scope\":[\"punctuation.definition.string\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Punctuation Definition String Markdown\",\"scope\":[\"punctuation.definition.string.begin.markdown\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Boolean\",\"scope\":[\"constant.language.boolean\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Object Comma\",\"scope\":[\"object.comma\"],\"settings\":{\"foreground\":\"#ffffff\"}},{\"name\":\"Variable Parameter Function\",\"scope\":[\"variable.parameter.function\"],\"settings\":{\"foreground\":\"#7fdbca\",\"fontStyle\":\"\"}},{\"name\":\"Support Type Property Name & entity name tags\",\"scope\":[\"support.type.vendor.property-name\",\"support.constant.vendor.property-value\",\"support.type.property-name\",\"meta.property-list entity.name.tag\"],\"settings\":{\"foreground\":\"#80cbc4\",\"fontStyle\":\"\"}},{\"name\":\"Entity Name tag reference in stylesheets\",\"scope\":[\"meta.property-list entity.name.tag.reference\"],\"settings\":{\"foreground\":\"#57eaf1\"}},{\"name\":\"Constant Other Color RGB Value Punctuation Definition Constant\",\"scope\":[\"constant.other.color.rgb-value punctuation.definition.constant\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Constant Other Color\",\"scope\":[\"constant.other.color\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Keyword Other Unit\",\"scope\":[\"keyword.other.unit\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Meta Selector\",\"scope\":[\"meta.selector\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Entity Other Attribute Name Id\",\"scope\":[\"entity.other.attribute-name.id\"],\"settings\":{\"foreground\":\"#fad430\"}},{\"name\":\"Meta Property Name\",\"scope\":[\"meta.property-name\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Doctypes\",\"scope\":[\"entity.name.tag.doctype\",\"meta.tag.sgml.doctype\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Punctuation Definition Parameters\",\"scope\":[\"punctuation.definition.parameters\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Keyword Control Operator\",\"scope\":[\"keyword.control.operator\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Keyword Operator Logical\",\"scope\":[\"keyword.operator.logical\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Variable Instances\",\"scope\":[\"variable.instance\",\"variable.other.instance\",\"variable.readwrite.instance\",\"variable.other.readwrite.instance\",\"variable.other.property\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Variable Property Other object property\",\"scope\":[\"variable.other.object.property\"],\"settings\":{\"foreground\":\"#faf39f\",\"fontStyle\":\"\"}},{\"name\":\"Variable Property Other object\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Entity Name Function\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#82aaff\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Comparison, returns, imports, and Keyword Operator Ruby\",\"scope\":[\"keyword.control.conditional.js\",\"keyword.operator.comparison\",\"keyword.control.flow.js\",\"keyword.control.flow.ts\",\"keyword.control.flow.tsx\",\"keyword.control.ruby\",\"keyword.control.def.ruby\",\"keyword.control.loop.js\",\"keyword.control.loop.ts\",\"keyword.control.import.js\",\"keyword.control.import.ts\",\"keyword.control.import.tsx\",\"keyword.control.from.js\",\"keyword.control.from.ts\",\"keyword.control.from.tsx\",\"keyword.control.conditional.js\",\"keyword.control.conditional.ts\",\"keyword.control.switch.js\",\"keyword.control.switch.ts\",\"keyword.operator.instanceof.js\",\"keyword.operator.expression.instanceof.ts\",\"keyword.operator.expression.instanceof.tsx\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords\",\"scope\":[\"support.constant\",\"keyword.other.special-method\",\"keyword.other.new\",\"keyword.other.debugger\",\"keyword.control\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Support Function\",\"scope\":[\"support.function\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Invalid Broken\",\"scope\":[\"invalid.broken\"],\"settings\":{\"foreground\":\"#989da0\",\"background\":\"#F78C6C\"}},{\"name\":\"Invalid Unimplemented\",\"scope\":[\"invalid.unimplemented\"],\"settings\":{\"background\":\"#8BD649\",\"foreground\":\"#ffffff\"}},{\"name\":\"Invalid Illegal\",\"scope\":[\"invalid.illegal\"],\"settings\":{\"foreground\":\"#ffffff\",\"background\":\"#ec5f67\"}},{\"name\":\"Language Variable\",\"scope\":[\"variable.language\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Support Variable Property\",\"scope\":[\"support.variable.property\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Variable Function\",\"scope\":[\"variable.function\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Variable Interpolation\",\"scope\":[\"variable.interpolation\"],\"settings\":{\"foreground\":\"#ef787f\"}},{\"name\":\"Meta Function Call\",\"scope\":[\"meta.function-call\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Punctuation Section Embedded\",\"scope\":[\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#e2817f\"}},{\"name\":\"Punctuation Tweaks\",\"scope\":[\"punctuation.terminator.expression\",\"punctuation.definition.arguments\",\"punctuation.definition.array\",\"punctuation.section.array\",\"meta.array\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"More Punctuation Tweaks\",\"scope\":[\"punctuation.definition.list.begin\",\"punctuation.definition.list.end\",\"punctuation.separator.arguments\",\"punctuation.definition.list\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Template Strings\",\"scope\":[\"string.template meta.template.expression\"],\"settings\":{\"foreground\":\"#e2817f\"}},{\"name\":\"Backticks(``) in Template Strings\",\"scope\":[\"string.template punctuation.definition.string\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Italics\",\"scope\":[\"italic\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"italic\"}},{\"name\":\"Bold\",\"scope\":[\"bold\"],\"settings\":{\"foreground\":\"#c5e478\",\"fontStyle\":\"bold\"}},{\"name\":\"Quote\",\"scope\":[\"quote\"],\"settings\":{\"foreground\":\"#969bb7\",\"fontStyle\":\"\"}},{\"name\":\"Raw Code\",\"scope\":[\"raw\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"CoffeeScript Variable Assignment\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#31e1eb\"}},{\"name\":\"CoffeeScript Parameter Function\",\"scope\":[\"variable.parameter.function.coffee\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"CoffeeScript Assignments\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"C# Readwrite Variables\",\"scope\":[\"variable.other.readwrite.cs\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C# Classes & Storage types\",\"scope\":[\"entity.name.type.class.cs\",\"storage.type.cs\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"C# Namespaces\",\"scope\":[\"entity.name.type.namespace.cs\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"C# Unquoted String Zone\",\"scope\":[\"string.unquoted.preprocessor.message.cs\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C# Region\",\"scope\":[\"punctuation.separator.hash.cs\",\"keyword.preprocessor.region.cs\",\"keyword.preprocessor.endregion.cs\"],\"settings\":{\"foreground\":\"#ffcb8b\",\"fontStyle\":\"bold\"}},{\"name\":\"C# Other Variables\",\"scope\":[\"variable.other.object.cs\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"C# Enum\",\"scope\":[\"entity.name.type.enum.cs\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Dart String\",\"scope\":[\"string.interpolated.single.dart\",\"string.interpolated.double.dart\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Dart Class\",\"scope\":[\"support.class.dart\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Tag names in Stylesheets\",\"scope\":[\"entity.name.tag.css\",\"entity.name.tag.less\",\"entity.name.tag.custom.css\",\"support.constant.property-value.css\"],\"settings\":{\"foreground\":\"#ff6d6d\",\"fontStyle\":\"\"}},{\"name\":\"Wildcard(*) selector in Stylesheets\",\"scope\":[\"entity.name.tag.wildcard.css\",\"entity.name.tag.wildcard.less\",\"entity.name.tag.wildcard.scss\",\"entity.name.tag.wildcard.sass\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"CSS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Attribute Name for CSS\",\"scope\":[\"meta.attribute-selector.css entity.other.attribute-name.attribute\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Elixir Classes\",\"scope\":[\"source.elixir support.type.elixir\",\"source.elixir meta.module.elixir entity.name.class.elixir\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Elixir Functions\",\"scope\":[\"source.elixir entity.name.function\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir Constants\",\"scope\":[\"source.elixir constant.other.symbol.elixir\",\"source.elixir constant.other.keywords.elixir\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Elixir String Punctuations\",\"scope\":[\"source.elixir punctuation.definition.string\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir\",\"scope\":[\"source.elixir variable.other.readwrite.module.elixir\",\"source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir Binary Punctuations\",\"scope\":[\"source.elixir .punctuation.binary.elixir\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Closure Constant Keyword\",\"scope\":[\"constant.keyword.clojure\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Go Function Calls\",\"scope\":[\"source.go meta.function-call.go\"],\"settings\":{\"foreground\":\"#dddddd\"}},{\"name\":\"Go Keywords\",\"scope\":[\"source.go keyword.package.go\",\"source.go keyword.import.go\",\"source.go keyword.function.go\",\"source.go keyword.type.go\",\"source.go keyword.struct.go\",\"source.go keyword.interface.go\",\"source.go keyword.const.go\",\"source.go keyword.var.go\",\"source.go keyword.map.go\",\"source.go keyword.channel.go\",\"source.go keyword.control.go\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Go Constants e.g. nil, string format (%s, %d, etc.)\",\"scope\":[\"source.go constant.language.go\",\"source.go constant.other.placeholder.go\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"C++ Functions\",\"scope\":[\"entity.name.function.preprocessor.cpp\",\"entity.scope.name.cpp\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"C++ Meta Namespace\",\"scope\":[\"meta.namespace-block.cpp\"],\"settings\":{\"foreground\":\"#e0dec6\"}},{\"name\":\"C++ Language Primitive Storage\",\"scope\":[\"storage.type.language.primitive.cpp\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"C++ Preprocessor Macro\",\"scope\":[\"meta.preprocessor.macro.cpp\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C++ Variable Parameter\",\"scope\":[\"variable.parameter\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Powershell Variables\",\"scope\":[\"variable.other.readwrite.powershell\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Powershell Function\",\"scope\":[\"support.function.powershell\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"ID Attribute Name in HTML\",\"scope\":[\"entity.other.attribute-name.id.html\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"HTML Punctuation Definition Tag\",\"scope\":[\"punctuation.definition.tag.html\"],\"settings\":{\"foreground\":\"#6ae9f0\"}},{\"name\":\"HTML Doctype\",\"scope\":[\"meta.tag.sgml.doctype.html\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Classes\",\"scope\":[\"meta.class entity.name.type.class.js\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"JavaScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.js\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"JavaScript Terminator\",\"scope\":[\"terminator.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Meta Punctuation Definition\",\"scope\":[\"meta.js punctuation.definition.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Entity Names in Code Documentations\",\"scope\":[\"entity.name.type.instance.jsdoc\",\"entity.name.type.instance.phpdoc\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"Other Variables in Code Documentations\",\"scope\":[\"variable.other.jsdoc\",\"variable.other.phpdoc\"],\"settings\":{\"foreground\":\"#78ccf0\"}},{\"name\":\"JavaScript module imports and exports\",\"scope\":[\"variable.other.meta.import.js\",\"meta.import.js variable.other\",\"variable.other.meta.export.js\",\"meta.export.js variable.other\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Variable Parameter Function\",\"scope\":[\"variable.parameter.function.js\"],\"settings\":{\"foreground\":\"#8b96ea\"}},{\"name\":\"JavaScript[React] Variable Other Object\",\"scope\":[\"variable.other.object.js\",\"variable.other.object.jsx\",\"variable.object.property.js\",\"variable.object.property.jsx\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Variables\",\"scope\":[\"variable.js\",\"variable.other.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Entity Name Type\",\"scope\":[\"entity.name.type.js\",\"entity.name.type.module.js\"],\"settings\":{\"foreground\":\"#ffcb8b\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Support Classes\",\"scope\":[\"support.class.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JSON Property Names\",\"scope\":[\"support.type.property-name.json\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"JSON Support Constants\",\"scope\":[\"support.constant.json\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"JSON Property values (string)\",\"scope\":[\"meta.structure.dictionary.value.json string.quoted.double\"],\"settings\":{\"foreground\":\"#c789d6\"}},{\"name\":\"Strings in JSON values\",\"scope\":[\"string.quoted.double.json punctuation.definition.string.json\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Specific JSON Property values like null\",\"scope\":[\"meta.structure.dictionary.json meta.structure.dictionary.value constant.language\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"JavaScript Other Variable\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Ruby Variables\",\"scope\":[\"variable.other.ruby\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Ruby Class\",\"scope\":[\"entity.name.type.class.ruby\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"Ruby Hashkeys\",\"scope\":[\"constant.language.symbol.hashkey.ruby\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"LESS Tag names\",\"scope\":[\"entity.name.tag.less\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"LESS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Attribute Name for LESS\",\"scope\":[\"meta.attribute-selector.less entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Markdown Headings\",\"scope\":[\"markup.heading.markdown\",\"markup.heading.setext.1.markdown\",\"markup.heading.setext.2.markdown\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown Italics\",\"scope\":[\"markup.italic.markdown\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"italic\"}},{\"name\":\"Markdown Bold\",\"scope\":[\"markup.bold.markdown\"],\"settings\":{\"foreground\":\"#c5e478\",\"fontStyle\":\"bold\"}},{\"name\":\"Markdown Quote + others\",\"scope\":[\"markup.quote.markdown\"],\"settings\":{\"foreground\":\"#969bb7\",\"fontStyle\":\"\"}},{\"name\":\"Markdown Raw Code + others\",\"scope\":[\"markup.inline.raw.markdown\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Markdown Links\",\"scope\":[\"markup.underline.link.markdown\",\"markup.underline.link.image.markdown\"],\"settings\":{\"foreground\":\"#ff869a\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Link Title and Description\",\"scope\":[\"string.other.link.title.markdown\",\"string.other.link.description.markdown\"],\"settings\":{\"foreground\":\"#d6deeb\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Punctuation\",\"scope\":[\"punctuation.definition.string.markdown\",\"punctuation.definition.string.begin.markdown\",\"punctuation.definition.string.end.markdown\",\"meta.link.inline.markdown punctuation.definition.string\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown MetaData Punctuation\",\"scope\":[\"punctuation.definition.metadata.markdown\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Markdown List Punctuation\",\"scope\":[\"beginning.punctuation.definition.list.markdown\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown Inline Raw String\",\"scope\":[\"markup.inline.raw.string.markdown\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"PHP Variables\",\"scope\":[\"variable.other.php\"],\"settings\":{\"foreground\":\"#bec5d4\"}},{\"name\":\"Support Classes in PHP\",\"scope\":[\"support.class.php\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Punctuations in PHP function calls\",\"scope\":[\"meta.function-call.php punctuation\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"PHP Global Variables\",\"scope\":[\"variable.other.global.php\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Declaration Punctuation in PHP Global Variables\",\"scope\":[\"variable.other.global.php punctuation.definition.variable\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Language Constants in Python\",\"scope\":[\"constant.language.python\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Python Function Parameter and Arguments\",\"scope\":[\"variable.parameter.function.python\",\"meta.function-call.arguments.python\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Python Function Call\",\"scope\":[\"meta.function-call.python\",\"meta.function-call.generic.python\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"Punctuations in Python\",\"scope\":[\"punctuation.python\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Decorator Functions in Python\",\"scope\":[\"entity.name.function.decorator.python\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Python Language Variable\",\"scope\":[\"source.python variable.language.special\"],\"settings\":{\"foreground\":\"#8eace3\"}},{\"name\":\"Python import control keyword\",\"scope\":[\"keyword.control\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"SCSS Variable\",\"scope\":[\"variable.scss\",\"variable.sass\",\"variable.parameter.url.scss\",\"variable.parameter.url.sass\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#bec5d4\"}},{\"name\":\"Attribute Name for SASS\",\"scope\":[\"meta.attribute-selector.scss entity.other.attribute-name.attribute\",\"meta.attribute-selector.sass entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Tag names in SASS\",\"scope\":[\"entity.name.tag.scss\",\"entity.name.tag.sass\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"SASS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.scss\",\"keyword.other.unit.sass\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"TypeScript[React] Variables and Object Properties\",\"scope\":[\"variable.other.readwrite.alias.ts\",\"variable.other.readwrite.alias.tsx\",\"variable.other.readwrite.ts\",\"variable.other.readwrite.tsx\",\"variable.other.object.ts\",\"variable.other.object.tsx\",\"variable.object.property.ts\",\"variable.object.property.tsx\",\"variable.other.ts\",\"variable.other.tsx\",\"variable.tsx\",\"variable.ts\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript[React] Entity Name Types\",\"scope\":[\"entity.name.type.ts\",\"entity.name.type.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript[React] Node Classes\",\"scope\":[\"support.class.node.ts\",\"support.class.node.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"TypeScript[React] Entity Name Types as Parameters\",\"scope\":[\"meta.type.parameters.ts entity.name.type\",\"meta.type.parameters.tsx entity.name.type\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"TypeScript[React] Import/Export Punctuations\",\"scope\":[\"meta.import.ts punctuation.definition.block\",\"meta.import.tsx punctuation.definition.block\",\"meta.export.ts punctuation.definition.block\",\"meta.export.tsx punctuation.definition.block\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.decorator punctuation.decorator.ts\",\"meta.decorator punctuation.decorator.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.tag.js meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"YAML Entity Name Tags\",\"scope\":[\"entity.name.tag.yaml\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"JavaScript Variable Other ReadWrite\",\"scope\":[\"variable.other.readwrite.js\",\"variable.parameter\"],\"settings\":{\"foreground\":\"#d7dbe0\"}},{\"name\":\"Support Class Component\",\"scope\":[\"support.class.component.js\",\"support.class.component.tsx\"],\"settings\":{\"foreground\":\"#f78c6c\",\"fontStyle\":\"\"}},{\"name\":\"Text nested in React tags\",\"scope\":[\"meta.jsx.children\",\"meta.jsx.children.js\",\"meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript Classes\",\"scope\":[\"meta.class entity.name.type.class.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript Entity Name Type\",\"scope\":[\"entity.name.type.tsx\",\"entity.name.type.module.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript Class Variable Keyword\",\"scope\":[\"meta.class.ts meta.var.expr.ts storage.type.ts\",\"meta.class.tsx meta.var.expr.tsx storage.type.tsx\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"TypeScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.ts\",\"meta.method.declaration storage.type.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"normalize font style of certain components\",\"scope\":[\"meta.property-list.css meta.property-value.css variable.other.less\",\"meta.property-list.scss variable.scss\",\"meta.property-list.sass variable.sass\",\"meta.brace\",\"keyword.operator.operator\",\"keyword.operator.or.regexp\",\"keyword.operator.expression.in\",\"keyword.operator.relational\",\"keyword.operator.assignment\",\"keyword.operator.comparison\",\"keyword.operator.type\",\"keyword.operator\",\"keyword\",\"punctuation.definition.string\",\"punctuation\",\"variable.other.readwrite.js\",\"storage.type\",\"source.css\",\"string.quoted\"],\"settings\":{\"fontStyle\":\"\"}}],\"styleOverrides\":{\"frames\":{\"editorBackground\":\"var(--sl-color-gray-6)\",\"terminalBackground\":\"var(--sl-color-gray-6)\",\"editorActiveTabBackground\":\"var(--sl-color-gray-6)\",\"terminalTitlebarDotsForeground\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"terminalTitlebarDotsOpacity\":\"0.75\",\"inlineButtonForeground\":\"var(--sl-color-text)\",\"frameBoxShadowCssValue\":\"none\"},\"textMarkers\":{\"markBackground\":\"#ffffff17\",\"markBorderColor\":\"#ffffff40\"}}},{\"name\":\"Night Owl Light\",\"type\":\"light\",\"colors\":{\"focusBorder\":\"#93a1a1\",\"foreground\":\"#403f53\",\"disabledForeground\":\"#61616180\",\"descriptionForeground\":\"#403f53\",\"errorForeground\":\"#403f53\",\"icon.foreground\":\"#424242\",\"contrastActiveBorder\":null,\"contrastBorder\":null,\"textBlockQuote.background\":\"#7f7f7f1a\",\"textBlockQuote.border\":\"#007acc80\",\"textCodeBlock.background\":\"#dcdcdc66\",\"textLink.activeForeground\":\"#006ab1\",\"textLink.foreground\":\"#006ab1\",\"textPreformat.foreground\":\"#a31515\",\"textSeparator.foreground\":\"#0000002e\",\"editor.background\":\"#f6f7f9\",\"editor.foreground\":\"#403f53\",\"editorLineNumber.foreground\":\"#90a7b2\",\"editorLineNumber.activeForeground\":\"#403f53\",\"editorActiveLineNumber.foreground\":\"#0b216f\",\"editor.selectionBackground\":\"#e0e0e0\",\"editor.inactiveSelectionBackground\":\"#e0e0e080\",\"editor.selectionHighlightBackground\":\"#339cec33\",\"editorError.foreground\":\"#e64d49\",\"editorWarning.foreground\":\"#daaa01\",\"editorInfo.foreground\":\"#1a85ff\",\"editorHint.foreground\":\"#6c6c6c\",\"problemsErrorIcon.foreground\":\"#e64d49\",\"problemsWarningIcon.foreground\":\"#daaa01\",\"problemsInfoIcon.foreground\":\"#1a85ff\",\"editor.findMatchBackground\":\"#93a1a16c\",\"editor.findMatchHighlightBackground\":\"#93a1a16c\",\"editor.findRangeHighlightBackground\":\"#7497a633\",\"editorLink.activeForeground\":\"#0000ff\",\"editorLightBulb.foreground\":\"#ddb100\",\"editorLightBulbAutoFix.foreground\":\"#007acc\",\"diffEditor.insertedTextBackground\":\"#9ccc2c40\",\"diffEditor.insertedTextBorder\":null,\"diffEditor.removedTextBackground\":\"#ff000033\",\"diffEditor.removedTextBorder\":null,\"diffEditor.insertedLineBackground\":\"#9bb95533\",\"diffEditor.removedLineBackground\":\"#ff000033\",\"editorStickyScroll.background\":\"#fbfbfb\",\"editorStickyScrollHover.background\":\"#f0f0f0\",\"editorInlayHint.background\":\"#2aa29899\",\"editorInlayHint.foreground\":\"#f0f0f0\",\"editorInlayHint.typeBackground\":\"#2aa29899\",\"editorInlayHint.typeForeground\":\"#f0f0f0\",\"editorInlayHint.parameterBackground\":\"#2aa29899\",\"editorInlayHint.parameterForeground\":\"#f0f0f0\",\"editorPane.background\":\"#fbfbfb\",\"editorGroup.emptyBackground\":null,\"editorGroup.focusedEmptyBorder\":null,\"editorGroupHeader.tabsBackground\":\"var(--sl-color-gray-6)\",\"editorGroupHeader.tabsBorder\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"editorGroupHeader.noTabsBackground\":\"#f0f0f0\",\"editorGroupHeader.border\":null,\"editorGroup.border\":\"#f0f0f0\",\"editorGroup.dropBackground\":\"#2677cb2d\",\"editorGroup.dropIntoPromptForeground\":\"#403f53\",\"editorGroup.dropIntoPromptBackground\":\"#f0f0f0\",\"editorGroup.dropIntoPromptBorder\":null,\"sideBySideEditor.horizontalBorder\":\"#f0f0f0\",\"sideBySideEditor.verticalBorder\":\"#f0f0f0\",\"scrollbar.shadow\":\"#cccccc\",\"scrollbarSlider.background\":\"#0000001a\",\"scrollbarSlider.hoverBackground\":\"#00000055\",\"scrollbarSlider.activeBackground\":\"#00000099\",\"panel.background\":\"#f0f0f0\",\"panel.border\":\"#d9d9d9\",\"panelTitle.activeBorder\":\"#424242\",\"panelTitle.activeForeground\":\"#424242\",\"panelTitle.inactiveForeground\":\"#424242bf\",\"panelSectionHeader.background\":\"#80808051\",\"terminal.background\":\"#f6f6f6\",\"widget.shadow\":\"#d9d9d9\",\"editorWidget.background\":\"#f0f0f0\",\"editorWidget.foreground\":\"#403f53\",\"editorWidget.border\":\"#d9d9d9\",\"quickInput.background\":\"#f0f0f0\",\"quickInput.foreground\":\"#403f53\",\"quickInputTitle.background\":\"#0000000f\",\"pickerGroup.foreground\":\"#403f53\",\"pickerGroup.border\":\"#d9d9d9\",\"editor.hoverHighlightBackground\":\"#339cec33\",\"editorHoverWidget.background\":\"#f0f0f0\",\"editorHoverWidget.foreground\":\"#403f53\",\"editorHoverWidget.border\":\"#d9d9d9\",\"editorHoverWidget.statusBarBackground\":\"#e4e4e4\",\"titleBar.activeBackground\":\"var(--sl-color-gray-6)\",\"titleBar.activeForeground\":\"var(--sl-color-text)\",\"titleBar.inactiveBackground\":\"#f0f0f099\",\"titleBar.inactiveForeground\":\"#33333399\",\"titleBar.border\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"toolbar.hoverBackground\":\"#b8b8b850\",\"toolbar.activeBackground\":\"#a6a6a650\",\"tab.activeBackground\":\"#f6f6f6\",\"tab.unfocusedActiveBackground\":\"#f6f6f6\",\"tab.inactiveBackground\":\"#f0f0f0\",\"tab.unfocusedInactiveBackground\":\"#f0f0f0\",\"tab.activeForeground\":\"var(--sl-color-text)\",\"tab.inactiveForeground\":\"#403f53\",\"tab.unfocusedActiveForeground\":\"#403f53b3\",\"tab.unfocusedInactiveForeground\":\"#403f5380\",\"tab.hoverBackground\":null,\"tab.unfocusedHoverBackground\":null,\"tab.hoverForeground\":null,\"tab.unfocusedHoverForeground\":null,\"tab.border\":\"#f0f0f0\",\"tab.lastPinnedBorder\":\"#a9a9a9\",\"tab.activeBorder\":\"transparent\",\"tab.unfocusedActiveBorder\":null,\"tab.activeBorderTop\":\"var(--sl-color-accent)\",\"tab.unfocusedActiveBorderTop\":null,\"tab.hoverBorder\":null,\"tab.unfocusedHoverBorder\":null,\"tab.activeModifiedBorder\":\"#2aa298\",\"tab.inactiveModifiedBorder\":\"#93a1a1\",\"tab.unfocusedActiveModifiedBorder\":\"#93a1a1\",\"tab.unfocusedInactiveModifiedBorder\":\"#93a1a1\",\"badge.background\":\"#2aa298\",\"badge.foreground\":\"#f0f0f0\",\"button.background\":\"#2aa298\",\"button.foreground\":\"#f0f0f0\",\"button.border\":null,\"button.separator\":\"#f0f0f066\",\"button.hoverBackground\":\"#22827a\",\"button.secondaryBackground\":\"#5f6a79\",\"button.secondaryForeground\":\"#ffffff\",\"button.secondaryHoverBackground\":\"#4c5561\",\"dropdown.background\":\"#f0f0f0\",\"dropdown.foreground\":\"#403f53\",\"dropdown.border\":\"#d9d9d9\",\"list.activeSelectionBackground\":\"#d3e8f8\",\"list.activeSelectionForeground\":\"#403f53\",\"tree.indentGuidesStroke\":\"#a9a9a9\",\"input.background\":\"#f0f0f0\",\"input.foreground\":\"#403f53\",\"input.placeholderForeground\":\"#93a1a1\",\"inputOption.activeBorder\":\"#2aa298\",\"inputOption.hoverBackground\":\"#b8b8b850\",\"inputOption.activeBackground\":\"#93a1a133\",\"inputOption.activeForeground\":\"#000000\",\"inputValidation.infoBackground\":\"#f0f0f0\",\"inputValidation.infoBorder\":\"#d0d0d0\",\"inputValidation.warningBackground\":\"#daaa01\",\"inputValidation.warningBorder\":\"#e0af02\",\"inputValidation.errorBackground\":\"#f76e6e\",\"inputValidation.errorBorder\":\"#de3d3b\",\"keybindingLabel.background\":\"#dddddd66\",\"keybindingLabel.foreground\":\"#555555\",\"keybindingLabel.border\":\"#cccccc66\",\"keybindingLabel.bottomBorder\":\"#bbbbbb66\",\"menu.foreground\":\"#403f53\",\"menu.background\":\"#f0f0f0\",\"menu.selectionForeground\":\"#403f53\",\"menu.selectionBackground\":\"#d3e8f8\",\"menu.separatorBackground\":\"#d4d4d4\",\"editor.snippetTabstopHighlightBackground\":\"#0a326433\",\"editor.snippetFinalTabstopHighlightBorder\":\"#0a326480\",\"terminal.ansiBlack\":\"#403f53\",\"terminal.ansiRed\":\"#de3d3b\",\"terminal.ansiGreen\":\"#08916a\",\"terminal.ansiYellow\":\"#e0af02\",\"terminal.ansiBlue\":\"#288ed7\",\"terminal.ansiMagenta\":\"#d6438a\",\"terminal.ansiCyan\":\"#2aa298\",\"terminal.ansiWhite\":\"#f0f0f0\",\"terminal.ansiBrightBlack\":\"#403f53\",\"terminal.ansiBrightRed\":\"#de3d3b\",\"terminal.ansiBrightGreen\":\"#08916a\",\"terminal.ansiBrightYellow\":\"#daaa01\",\"terminal.ansiBrightBlue\":\"#288ed7\",\"terminal.ansiBrightMagenta\":\"#d6438a\",\"terminal.ansiBrightCyan\":\"#2aa298\",\"terminal.ansiBrightWhite\":\"#f0f0f0\",\"selection.background\":\"#7a8181ad\",\"notifications.background\":\"#f0f0f0\",\"notifications.foreground\":\"#403f53\",\"notificationLink.foreground\":\"#994cc3\",\"notifications.border\":\"#cccccc\",\"notificationCenter.border\":\"#cccccc\",\"notificationToast.border\":\"#cccccc\",\"notificationCenterHeader.foreground\":\"#403f53\",\"notificationCenterHeader.background\":\"#f0f0f0\",\"input.border\":\"#d9d9d9\",\"progressBar.background\":\"#2aa298\",\"list.inactiveSelectionBackground\":\"#e0e7ea\",\"list.inactiveSelectionForeground\":\"#403f53\",\"list.focusBackground\":\"#d3e8f8\",\"list.hoverBackground\":\"#d3e8f8\",\"list.focusForeground\":\"#403f53\",\"list.hoverForeground\":\"#403f53\",\"list.highlightForeground\":\"#403f53\",\"list.errorForeground\":\"#e64d49\",\"list.warningForeground\":\"#daaa01\",\"activityBar.background\":\"#f0f0f0\",\"activityBar.foreground\":\"#403f53\",\"activityBar.dropBackground\":\"#d0d0d0\",\"activityBarBadge.background\":\"#403f53\",\"activityBarBadge.foreground\":\"#f0f0f0\",\"activityBar.border\":\"#f0f0f0\",\"sideBar.background\":\"#f0f0f0\",\"sideBar.foreground\":\"#403f53\",\"sideBarTitle.foreground\":\"#403f53\",\"sideBar.border\":\"#f0f0f0\",\"editorGroup.background\":\"#f6f6f6\",\"editorCursor.foreground\":\"#90a7b2\",\"editor.wordHighlightBackground\":\"#339cec33\",\"editor.wordHighlightStrongBackground\":\"#007dd659\",\"editor.lineHighlightBackground\":\"#f0f0f0\",\"editor.rangeHighlightBackground\":\"#7497a633\",\"editorWhitespace.foreground\":\"#d9d9d9\",\"editorIndentGuide.background\":\"#d9d9d9\",\"editorCodeLens.foreground\":\"#403f53\",\"editorBracketMatch.background\":\"#d3e8f8\",\"editorBracketMatch.border\":\"#2aa298\",\"editorError.border\":\"#fbfbfb\",\"editorWarning.border\":\"#daaa01\",\"editorGutter.addedBackground\":\"#49d0c5\",\"editorGutter.modifiedBackground\":\"#6fbef6\",\"editorGutter.deletedBackground\":\"#f76e6e\",\"editorRuler.foreground\":\"#d9d9d9\",\"editorOverviewRuler.errorForeground\":\"#e64d49\",\"editorOverviewRuler.warningForeground\":\"#daaa01\",\"editorSuggestWidget.background\":\"#f0f0f0\",\"editorSuggestWidget.foreground\":\"#403f53\",\"editorSuggestWidget.highlightForeground\":\"#403f53\",\"editorSuggestWidget.selectedBackground\":\"#d3e8f8\",\"editorSuggestWidget.border\":\"#d9d9d9\",\"debugExceptionWidget.background\":\"#f0f0f0\",\"debugExceptionWidget.border\":\"#d9d9d9\",\"editorMarkerNavigation.background\":\"#d0d0d0\",\"editorMarkerNavigationError.background\":\"#f76e6e\",\"editorMarkerNavigationWarning.background\":\"#daaa01\",\"debugToolBar.background\":\"#f0f0f0\",\"extensionButton.prominentBackground\":\"#2aa298\",\"extensionButton.prominentForeground\":\"#f0f0f0\",\"statusBar.background\":\"#f0f0f0\",\"statusBar.border\":\"#f0f0f0\",\"statusBar.debuggingBackground\":\"#f0f0f0\",\"statusBar.debuggingForeground\":\"#403f53\",\"statusBar.foreground\":\"#403f53\",\"statusBar.noFolderBackground\":\"#f0f0f0\",\"statusBar.noFolderForeground\":\"#403f53\",\"peekView.border\":\"#d9d9d9\",\"peekViewEditor.background\":\"#f6f6f6\",\"peekViewEditorGutter.background\":\"#f6f6f6\",\"peekViewEditor.matchHighlightBackground\":\"#49d0c5\",\"peekViewResult.background\":\"#f0f0f0\",\"peekViewResult.fileForeground\":\"#403f53\",\"peekViewResult.lineForeground\":\"#403f53\",\"peekViewResult.matchHighlightBackground\":\"#49d0c5\",\"peekViewResult.selectionBackground\":\"#e0e7ea\",\"peekViewResult.selectionForeground\":\"#403f53\",\"peekViewTitle.background\":\"#f0f0f0\",\"peekViewTitleLabel.foreground\":\"#403f53\",\"peekViewTitleDescription.foreground\":\"#403f53\",\"terminal.foreground\":\"#403f53\"},\"fg\":\"#403f53\",\"bg\":\"#f6f7f9\",\"semanticHighlighting\":false,\"settings\":[{\"name\":\"Changed\",\"scope\":[\"markup.changed\",\"meta.diff.header.git\",\"meta.diff.header.from-file\",\"meta.diff.header.to-file\"],\"settings\":{\"foreground\":\"#556484\"}},{\"name\":\"Deleted\",\"scope\":[\"markup.deleted.diff\"],\"settings\":{\"foreground\":\"#ae3c3afd\"}},{\"name\":\"Inserted\",\"scope\":[\"markup.inserted.diff\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Global settings\",\"settings\":{\"background\":\"#011627\",\"foreground\":\"#403f53\"}},{\"name\":\"Comment\",\"scope\":[\"comment\"],\"settings\":{\"foreground\":\"#5f636f\"}},{\"name\":\"String\",\"scope\":[\"string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"String Quoted\",\"scope\":[\"string.quoted\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Support Constant Math\",\"scope\":[\"support.constant.math\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Number\",\"scope\":[\"constant.numeric\",\"constant.character.numeric\"],\"settings\":{\"foreground\":\"#aa0982\",\"fontStyle\":\"\"}},{\"name\":\"Built-in constant\",\"scope\":[\"constant.language\",\"punctuation.definition.constant\",\"variable.other.constant\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"User-defined constant\",\"scope\":[\"constant.character\",\"constant.other\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Constant Character Escape\",\"scope\":[\"constant.character.escape\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"RegExp String\",\"scope\":[\"string.regexp\",\"string.regexp keyword.other\"],\"settings\":{\"foreground\":\"#3a688f\"}},{\"name\":\"Comma in functions\",\"scope\":[\"meta.function punctuation.separator.comma\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"Variable\",\"scope\":[\"variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Keyword\",\"scope\":[\"punctuation.accessor\",\"keyword\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage\",\"scope\":[\"storage\",\"meta.var.expr\",\"meta.class meta.method.declaration meta.var.expr storage.type.js\",\"storage.type.property.js\",\"storage.type.property.ts\",\"storage.type.property.tsx\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type.function.arrow.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Class name\",\"scope\":[\"entity.name.class\",\"meta.class entity.name.type.class\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Inherited class\",\"scope\":[\"entity.other.inherited-class\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Function name\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Meta Tag\",\"scope\":[\"punctuation.definition.tag\",\"meta.tag\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"HTML Tag names\",\"scope\":[\"entity.name.tag\",\"meta.tag.other.html\",\"meta.tag.other.js\",\"meta.tag.other.tsx\",\"entity.name.tag.tsx\",\"entity.name.tag.js\",\"entity.name.tag\",\"meta.tag.js\",\"meta.tag.tsx\",\"meta.tag.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Tag attribute\",\"scope\":[\"entity.other.attribute-name\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Entity Name Tag Custom\",\"scope\":[\"entity.name.tag.custom\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Library (function & constant)\",\"scope\":[\"support.function\",\"support.constant\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Support Constant Property Value meta\",\"scope\":[\"support.constant.meta.property-value\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Library class/type\",\"scope\":[\"support.type\",\"support.class\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Support Variable DOM\",\"scope\":[\"support.variable.dom\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Invalid\",\"scope\":[\"invalid\"],\"settings\":{\"foreground\":\"#bb2060\"}},{\"name\":\"Invalid deprecated\",\"scope\":[\"invalid.deprecated\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Keyword Operator\",\"scope\":[\"keyword.operator\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Relational\",\"scope\":[\"keyword.operator.relational\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Assignment\",\"scope\":[\"keyword.operator.assignment\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Arithmetic\",\"scope\":[\"keyword.operator.arithmetic\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Bitwise\",\"scope\":[\"keyword.operator.bitwise\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Increment\",\"scope\":[\"keyword.operator.increment\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Ternary\",\"scope\":[\"keyword.operator.ternary\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Double-Slashed Comment\",\"scope\":[\"comment.line.double-slash\"],\"settings\":{\"foreground\":\"#5d6376\"}},{\"name\":\"Object\",\"scope\":[\"object\"],\"settings\":{\"foreground\":\"#58656a\"}},{\"name\":\"Null\",\"scope\":[\"constant.language.null\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Meta Brace\",\"scope\":[\"meta.brace\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Meta Delimiter Period\",\"scope\":[\"meta.delimiter.period\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Punctuation Definition String\",\"scope\":[\"punctuation.definition.string\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Punctuation Definition String Markdown\",\"scope\":[\"punctuation.definition.string.begin.markdown\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Boolean\",\"scope\":[\"constant.language.boolean\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Object Comma\",\"scope\":[\"object.comma\"],\"settings\":{\"foreground\":\"#646464\"}},{\"name\":\"Variable Parameter Function\",\"scope\":[\"variable.parameter.function\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Support Type Property Name & entity name tags\",\"scope\":[\"support.type.vendor.property-name\",\"support.constant.vendor.property-value\",\"support.type.property-name\",\"meta.property-list entity.name.tag\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Entity Name tag reference in stylesheets\",\"scope\":[\"meta.property-list entity.name.tag.reference\"],\"settings\":{\"foreground\":\"#286d70\"}},{\"name\":\"Constant Other Color RGB Value Punctuation Definition Constant\",\"scope\":[\"constant.other.color.rgb-value punctuation.definition.constant\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Constant Other Color\",\"scope\":[\"constant.other.color\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Keyword Other Unit\",\"scope\":[\"keyword.other.unit\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Meta Selector\",\"scope\":[\"meta.selector\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Entity Other Attribute Name Id\",\"scope\":[\"entity.other.attribute-name.id\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Meta Property Name\",\"scope\":[\"meta.property-name\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Doctypes\",\"scope\":[\"entity.name.tag.doctype\",\"meta.tag.sgml.doctype\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Punctuation Definition Parameters\",\"scope\":[\"punctuation.definition.parameters\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Keyword Control Operator\",\"scope\":[\"keyword.control.operator\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Keyword Operator Logical\",\"scope\":[\"keyword.operator.logical\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"\"}},{\"name\":\"Variable Instances\",\"scope\":[\"variable.instance\",\"variable.other.instance\",\"variable.readwrite.instance\",\"variable.other.readwrite.instance\",\"variable.other.property\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Variable Property Other object property\",\"scope\":[\"variable.other.object.property\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Variable Property Other object\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Entity Name Function\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Keyword Operator Comparison, imports, returns and Keyword Operator Ruby\",\"scope\":[\"keyword.operator.comparison\",\"keyword.control.flow.js\",\"keyword.control.flow.ts\",\"keyword.control.flow.tsx\",\"keyword.control.ruby\",\"keyword.control.module.ruby\",\"keyword.control.class.ruby\",\"keyword.control.def.ruby\",\"keyword.control.loop.js\",\"keyword.control.loop.ts\",\"keyword.control.import.js\",\"keyword.control.import.ts\",\"keyword.control.import.tsx\",\"keyword.control.from.js\",\"keyword.control.from.ts\",\"keyword.control.from.tsx\",\"keyword.operator.instanceof.js\",\"keyword.operator.expression.instanceof.ts\",\"keyword.operator.expression.instanceof.tsx\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Control Conditional\",\"scope\":[\"keyword.control.conditional.js\",\"keyword.control.conditional.ts\",\"keyword.control.switch.js\",\"keyword.control.switch.ts\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"\"}},{\"name\":\"Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords\",\"scope\":[\"support.constant\",\"keyword.other.special-method\",\"keyword.other.new\",\"keyword.other.debugger\",\"keyword.control\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Support Function\",\"scope\":[\"support.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Invalid Broken\",\"scope\":[\"invalid.broken\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Invalid Unimplemented\",\"scope\":[\"invalid.unimplemented\"],\"settings\":{\"foreground\":\"#486e26\"}},{\"name\":\"Invalid Illegal\",\"scope\":[\"invalid.illegal\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Language Variable\",\"scope\":[\"variable.language\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Support Variable Property\",\"scope\":[\"support.variable.property\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Variable Function\",\"scope\":[\"variable.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variable Interpolation\",\"scope\":[\"variable.interpolation\"],\"settings\":{\"foreground\":\"#a64348\"}},{\"name\":\"Meta Function Call\",\"scope\":[\"meta.function-call\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Punctuation Section Embedded\",\"scope\":[\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Punctuation Tweaks\",\"scope\":[\"punctuation.terminator.expression\",\"punctuation.definition.arguments\",\"punctuation.definition.array\",\"punctuation.section.array\",\"meta.array\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"More Punctuation Tweaks\",\"scope\":[\"punctuation.definition.list.begin\",\"punctuation.definition.list.end\",\"punctuation.separator.arguments\",\"punctuation.definition.list\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Template Strings\",\"scope\":[\"string.template meta.template.expression\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Backticks(``) in Template Strings\",\"scope\":[\"string.template punctuation.definition.string\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Italics\",\"scope\":[\"italic\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"italic\"}},{\"name\":\"Bold\",\"scope\":[\"bold\"],\"settings\":{\"foreground\":\"#3b61b0\",\"fontStyle\":\"bold\"}},{\"name\":\"Quote\",\"scope\":[\"quote\"],\"settings\":{\"foreground\":\"#5c6285\"}},{\"name\":\"Raw Code\",\"scope\":[\"raw\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"CoffeeScript Variable Assignment\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#186e73\"}},{\"name\":\"CoffeeScript Parameter Function\",\"scope\":[\"variable.parameter.function.coffee\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"CoffeeScript Assignments\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"C# Readwrite Variables\",\"scope\":[\"variable.other.readwrite.cs\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"C# Classes & Storage types\",\"scope\":[\"entity.name.type.class.cs\",\"storage.type.cs\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"C# Namespaces\",\"scope\":[\"entity.name.type.namespace.cs\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Tag names in Stylesheets\",\"scope\":[\"entity.name.tag.css\",\"entity.name.tag.less\",\"entity.name.tag.custom.css\",\"support.constant.property-value.css\"],\"settings\":{\"foreground\":\"#984e4d\",\"fontStyle\":\"\"}},{\"name\":\"Wildcard(*) selector in Stylesheets\",\"scope\":[\"entity.name.tag.wildcard.css\",\"entity.name.tag.wildcard.less\",\"entity.name.tag.wildcard.scss\",\"entity.name.tag.wildcard.sass\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"CSS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Attribute Name for CSS\",\"scope\":[\"meta.attribute-selector.css entity.other.attribute-name.attribute\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Elixir Classes\",\"scope\":[\"source.elixir support.type.elixir\",\"source.elixir meta.module.elixir entity.name.class.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Functions\",\"scope\":[\"source.elixir entity.name.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Constants\",\"scope\":[\"source.elixir constant.other.symbol.elixir\",\"source.elixir constant.other.keywords.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir String Punctuations\",\"scope\":[\"source.elixir punctuation.definition.string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir\",\"scope\":[\"source.elixir variable.other.readwrite.module.elixir\",\"source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Binary Punctuations\",\"scope\":[\"source.elixir .punctuation.binary.elixir\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Closure Constant Keyword\",\"scope\":[\"constant.keyword.clojure\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Go Function Calls\",\"scope\":[\"source.go meta.function-call.go\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Go Keywords\",\"scope\":[\"source.go keyword.package.go\",\"source.go keyword.import.go\",\"source.go keyword.function.go\",\"source.go keyword.type.go\",\"source.go keyword.struct.go\",\"source.go keyword.interface.go\",\"source.go keyword.const.go\",\"source.go keyword.var.go\",\"source.go keyword.map.go\",\"source.go keyword.channel.go\",\"source.go keyword.control.go\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Go Constants e.g. nil, string format (%s, %d, etc.)\",\"scope\":[\"source.go constant.language.go\",\"source.go constant.other.placeholder.go\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"C++ Functions\",\"scope\":[\"entity.name.function.preprocessor.cpp\",\"entity.scope.name.cpp\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"C++ Meta Namespace\",\"scope\":[\"meta.namespace-block.cpp\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"C++ Language Primitive Storage\",\"scope\":[\"storage.type.language.primitive.cpp\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"C++ Preprocessor Macro\",\"scope\":[\"meta.preprocessor.macro.cpp\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"C++ Variable Parameter\",\"scope\":[\"variable.parameter\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Powershell Variables\",\"scope\":[\"variable.other.readwrite.powershell\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Powershell Function\",\"scope\":[\"support.function.powershell\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"ID Attribute Name in HTML\",\"scope\":[\"entity.other.attribute-name.id.html\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"HTML Punctuation Definition Tag\",\"scope\":[\"punctuation.definition.tag.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"HTML Doctype\",\"scope\":[\"meta.tag.sgml.doctype.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"JavaScript Classes\",\"scope\":[\"meta.class entity.name.type.class.js\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"JavaScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.js\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"JavaScript Terminator\",\"scope\":[\"terminator.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Meta Punctuation Definition\",\"scope\":[\"meta.js punctuation.definition.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Entity Names in Code Documentations\",\"scope\":[\"entity.name.type.instance.jsdoc\",\"entity.name.type.instance.phpdoc\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"Other Variables in Code Documentations\",\"scope\":[\"variable.other.jsdoc\",\"variable.other.phpdoc\"],\"settings\":{\"foreground\":\"#3e697c\"}},{\"name\":\"JavaScript module imports and exports\",\"scope\":[\"variable.other.meta.import.js\",\"meta.import.js variable.other\",\"variable.other.meta.export.js\",\"meta.export.js variable.other\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Variable Parameter Function\",\"scope\":[\"variable.parameter.function.js\"],\"settings\":{\"foreground\":\"#555ea2\"}},{\"name\":\"JavaScript[React] Variable Other Object\",\"scope\":[\"variable.other.object.js\",\"variable.other.object.jsx\",\"variable.object.property.js\",\"variable.object.property.jsx\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Variables\",\"scope\":[\"variable.js\",\"variable.other.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Entity Name Type\",\"scope\":[\"entity.name.type.js\",\"entity.name.type.module.js\"],\"settings\":{\"foreground\":\"#111111\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Support Classes\",\"scope\":[\"support.class.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JSON Property Names\",\"scope\":[\"support.type.property-name.json\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"JSON Support Constants\",\"scope\":[\"support.constant.json\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"JSON Property values (string)\",\"scope\":[\"meta.structure.dictionary.value.json string.quoted.double\"],\"settings\":{\"foreground\":\"#7c5686\"}},{\"name\":\"Strings in JSON values\",\"scope\":[\"string.quoted.double.json punctuation.definition.string.json\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Specific JSON Property values like null\",\"scope\":[\"meta.structure.dictionary.json meta.structure.dictionary.value constant.language\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"JavaScript Other Variable\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Ruby Variables\",\"scope\":[\"variable.other.ruby\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Ruby Class\",\"scope\":[\"entity.name.type.class.ruby\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Ruby Hashkeys\",\"scope\":[\"constant.language.symbol.hashkey.ruby\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Ruby Symbols\",\"scope\":[\"constant.language.symbol.ruby\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"LESS Tag names\",\"scope\":[\"entity.name.tag.less\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"LESS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Attribute Name for LESS\",\"scope\":[\"meta.attribute-selector.less entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Markdown Headings\",\"scope\":[\"markup.heading.markdown\",\"markup.heading.setext.1.markdown\",\"markup.heading.setext.2.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown Italics\",\"scope\":[\"markup.italic.markdown\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"italic\"}},{\"name\":\"Markdown Bold\",\"scope\":[\"markup.bold.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\",\"fontStyle\":\"bold\"}},{\"name\":\"Markdown Quote + others\",\"scope\":[\"markup.quote.markdown\"],\"settings\":{\"foreground\":\"#5c6285\"}},{\"name\":\"Markdown Raw Code + others\",\"scope\":[\"markup.inline.raw.markdown\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Markdown Links\",\"scope\":[\"markup.underline.link.markdown\",\"markup.underline.link.image.markdown\"],\"settings\":{\"foreground\":\"#954f5a\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Link Title and Description\",\"scope\":[\"string.other.link.title.markdown\",\"string.other.link.description.markdown\"],\"settings\":{\"foreground\":\"#403f53\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Punctuation\",\"scope\":[\"punctuation.definition.string.markdown\",\"punctuation.definition.string.begin.markdown\",\"punctuation.definition.string.end.markdown\",\"meta.link.inline.markdown punctuation.definition.string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown MetaData Punctuation\",\"scope\":[\"punctuation.definition.metadata.markdown\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Markdown List Punctuation\",\"scope\":[\"beginning.punctuation.definition.list.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown Inline Raw String\",\"scope\":[\"markup.inline.raw.string.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"PHP Variables\",\"scope\":[\"variable.other.php\",\"variable.other.property.php\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Support Classes in PHP\",\"scope\":[\"support.class.php\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Punctuations in PHP function calls\",\"scope\":[\"meta.function-call.php punctuation\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"PHP Global Variables\",\"scope\":[\"variable.other.global.php\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Declaration Punctuation in PHP Global Variables\",\"scope\":[\"variable.other.global.php punctuation.definition.variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Language Constants in Python\",\"scope\":[\"constant.language.python\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Python Function Parameter and Arguments\",\"scope\":[\"variable.parameter.function.python\",\"meta.function-call.arguments.python\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Python Function Call\",\"scope\":[\"meta.function-call.python\",\"meta.function-call.generic.python\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Punctuations in Python\",\"scope\":[\"punctuation.python\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Decorator Functions in Python\",\"scope\":[\"entity.name.function.decorator.python\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Python Language Variable\",\"scope\":[\"source.python variable.language.special\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Python import control keyword\",\"scope\":[\"keyword.control\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"SCSS Variable\",\"scope\":[\"variable.scss\",\"variable.sass\",\"variable.parameter.url.scss\",\"variable.parameter.url.sass\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Attribute Name for SASS\",\"scope\":[\"meta.attribute-selector.scss entity.other.attribute-name.attribute\",\"meta.attribute-selector.sass entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Tag names in SASS\",\"scope\":[\"entity.name.tag.scss\",\"entity.name.tag.sass\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"SASS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.scss\",\"keyword.other.unit.sass\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"TypeScript[React] Variables and Object Properties\",\"scope\":[\"variable.other.readwrite.alias.ts\",\"variable.other.readwrite.alias.tsx\",\"variable.other.readwrite.ts\",\"variable.other.readwrite.tsx\",\"variable.other.object.ts\",\"variable.other.object.tsx\",\"variable.object.property.ts\",\"variable.object.property.tsx\",\"variable.other.ts\",\"variable.other.tsx\",\"variable.tsx\",\"variable.ts\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript[React] Entity Name Types\",\"scope\":[\"entity.name.type.ts\",\"entity.name.type.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript[React] Node Classes\",\"scope\":[\"support.class.node.ts\",\"support.class.node.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"TypeScript[React] Entity Name Types as Parameters\",\"scope\":[\"meta.type.parameters.ts entity.name.type\",\"meta.type.parameters.tsx entity.name.type\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"TypeScript[React] Import/Export Punctuations\",\"scope\":[\"meta.import.ts punctuation.definition.block\",\"meta.import.tsx punctuation.definition.block\",\"meta.export.ts punctuation.definition.block\",\"meta.export.tsx punctuation.definition.block\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.decorator punctuation.decorator.ts\",\"meta.decorator punctuation.decorator.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.tag.js meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"YAML Entity Name Tags\",\"scope\":[\"entity.name.tag.yaml\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"JavaScript Variable Other ReadWrite\",\"scope\":[\"variable.other.readwrite.js\",\"variable.parameter\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Support Class Component\",\"scope\":[\"support.class.component.js\",\"support.class.component.tsx\"],\"settings\":{\"foreground\":\"#aa0982\",\"fontStyle\":\"\"}},{\"name\":\"Text nested in React tags\",\"scope\":[\"meta.jsx.children\",\"meta.jsx.children.js\",\"meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript Classes\",\"scope\":[\"meta.class entity.name.type.class.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript Entity Name Type\",\"scope\":[\"entity.name.type.tsx\",\"entity.name.type.module.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript Class Variable Keyword\",\"scope\":[\"meta.class.ts meta.var.expr.ts storage.type.ts\",\"meta.class.tsx meta.var.expr.tsx storage.type.tsx\"],\"settings\":{\"foreground\":\"#76578b\"}},{\"name\":\"TypeScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.ts\",\"meta.method.declaration storage.type.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"normalize font style of certain components\",\"scope\":[\"meta.property-list.css meta.property-value.css variable.other.less\",\"meta.property-list.scss variable.scss\",\"meta.property-list.sass variable.sass\",\"meta.brace\",\"keyword.operator.operator\",\"keyword.operator.or.regexp\",\"keyword.operator.expression.in\",\"keyword.operator.relational\",\"keyword.operator.assignment\",\"keyword.operator.comparison\",\"keyword.operator.type\",\"keyword.operator\",\"keyword\",\"punctuation.definition.string\",\"punctuation\",\"variable.other.readwrite.js\",\"storage.type\",\"source.css\",\"string.quoted\"],\"settings\":{\"fontStyle\":\"\"}}],\"styleOverrides\":{\"frames\":{\"editorBackground\":\"var(--sl-color-gray-7)\",\"terminalBackground\":\"var(--sl-color-gray-7)\",\"editorActiveTabBackground\":\"var(--sl-color-gray-7)\",\"terminalTitlebarDotsForeground\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"terminalTitlebarDotsOpacity\":\"0.75\",\"inlineButtonForeground\":\"var(--sl-color-text)\",\"frameBoxShadowCssValue\":\"none\"},\"textMarkers\":{\"markBackground\":\"#0000001a\",\"markBorderColor\":\"#00000055\"}}}],\"defaultLocale\":\"en\",\"cascadeLayer\":\"starlight.components\",\"styleOverrides\":{\"borderRadius\":\"0px\",\"borderWidth\":\"1px\",\"codePaddingBlock\":\"0.75rem\",\"codePaddingInline\":\"1rem\",\"codeFontFamily\":\"var(--__sl-font-mono)\",\"codeFontSize\":\"var(--sl-text-code)\",\"codeLineHeight\":\"var(--sl-line-height)\",\"uiFontFamily\":\"var(--__sl-font)\",\"textMarkers\":{\"lineDiffIndicatorMarginLeft\":\"0.25rem\",\"defaultChroma\":\"45\",\"backgroundOpacity\":\"60%\"}},\"plugins\":[{\"name\":\"Starlight Plugin\",\"hooks\":{}},{\"name\":\"astro-expressive-code\",\"hooks\":{}}]}]],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true,\"allowedDomains\":[],\"actionBodySizeLimit\":1048576},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"headingIdCompat\":false,\"preserveScriptOrder\":false,\"liveContentCollections\":false,\"csp\":false,\"staticImportMetaEnv\":false,\"chromeDevtoolsWorkspace\":false,\"failOnPrerenderConflict\":false,\"svgo\":false},\"legacy\":{\"collections\":false},\"prefetch\":{\"prefetchAll\":true},\"i18n\":{\"defaultLocale\":\"en\",\"locales\":[\"en\"],\"routing\":{\"prefixDefaultLocale\":false,\"redirectToDefaultLocale\":false,\"fallbackType\":\"redirect\"}}}","docs",["Map",11,12,26,27,46,47,65,66,88,89,107,108,126,127,148,149],"index",{"id":11,"data":13,"filePath":24,"digest":25,"deferredRender":16},{"title":14,"description":15,"editUrl":16,"head":17,"template":18,"hero":19,"sidebar":21,"pagefind":16,"draft":22},"Vonage Voice API Workshop","Let's build some sample applications!",true,[],"splash",{"tagline":15,"actions":20},[],{"hidden":22,"attrs":23},false,{},"src/content/docs/index.mdx","46148d68185c9a1e","02_setup_application",{"id":26,"data":28,"body":35,"filePath":36,"digest":37,"rendered":38},{"title":29,"description":30,"editUrl":16,"head":31,"template":32,"sidebar":33,"pagefind":16,"draft":22},"Setup Application","Create an application.",[],"doc",{"hidden":22,"attrs":34},{},"> Note: Please make sure to redeem the coupon code to your Vonage account's \u003Ca href=\"https://dashboard.vonage.com/coupons\" target=\"_blank\">dashboard\u003C/a> before continuing. It is needed to purchase a phone number.\n\nIn the terminal below, you should see a set up script running asking for your `API key`. Complete the steps in the set up script. This will create an Application with Voice functionality, purchase a phone number, and create the needed Webhook endpoints.\n\n> Note: You can get your credentials in the \u003Ca href=\"https://dashboard.vonage.com/settings\" target=\"_blank\">Vonage dashboard Settings Page\u003C/a>\n\nIf successful, you should see `APPLICATION READY` with a URL. Click the link to open in a new window or tab.","src/content/docs/02_Setup_Application.md","41ac2dedeb3ab62b",{"html":39,"metadata":40},"\u003Cblockquote>\n\u003Cp>Note: Please make sure to redeem the coupon code to your Vonage account’s \u003Ca href=\"https://dashboard.vonage.com/coupons\" target=\"_blank\">dashboard\u003C/a> before continuing. It is needed to purchase a phone number.\u003C/p>\n\u003C/blockquote>\n\u003Cp>In the terminal below, you should see a set up script running asking for your \u003Ccode dir=\"auto\">API key\u003C/code>. Complete the steps in the set up script. This will create an Application with Voice functionality, purchase a phone number, and create the needed Webhook endpoints.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Note: You can get your credentials in the \u003Ca href=\"https://dashboard.vonage.com/settings\" target=\"_blank\">Vonage dashboard Settings Page\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cp>If successful, you should see \u003Ccode dir=\"auto\">APPLICATION READY\u003C/code> with a URL. Click the link to open in a new window or tab.\u003C/p>",{"headings":41,"localImagePaths":42,"remoteImagePaths":43,"frontmatter":44,"imagePaths":45},[],[],[],{"title":29,"description":30},[],"01_create_account",{"id":46,"data":48,"body":54,"filePath":55,"digest":56,"rendered":57},{"title":49,"description":50,"editUrl":16,"head":51,"template":32,"sidebar":52,"pagefind":16,"draft":22},"Create an Account","Create a Vonage account.",[],{"hidden":22,"attrs":53},{},"First, a Vonage account is needed to get the credentials to set up this workshop applications. You can sign up for your account here: \u003Ca href=\"https://dashboard.vonage.com\" target=\"_blank\">Vonage dashboard\u003C/a>\n\nHere's a coupon to add money to your account:\n\nIf your account is in US dollars:\n\n```html\nTorcWebUS2026\n```\n\nIf your account is in Euros:\n\n```html\nTorcWebEUR2026\n```\n\n> Note: Make sure to copy your API Key and API Secret somewhere. We will need it in the next step.","src/content/docs/01_Create_Account.md","0434ab7976c6a491",{"html":58,"metadata":59},"\u003Cp>First, a Vonage account is needed to get the credentials to set up this workshop applications. You can sign up for your account here: \u003Ca href=\"https://dashboard.vonage.com\" target=\"_blank\">Vonage dashboard\u003C/a>\u003C/p>\n\u003Cp>Here’s a coupon to add money to your account:\u003C/p>\n\u003Cp>If your account is in US dollars:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">TorcWebUS2026\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"TorcWebUS2026\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>If your account is in Euros:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">TorcWebEUR2026\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"TorcWebEUR2026\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Note: Make sure to copy your API Key and API Secret somewhere. We will need it in the next step.\u003C/p>\n\u003C/blockquote>",{"headings":60,"localImagePaths":61,"remoteImagePaths":62,"frontmatter":63,"imagePaths":64},[],[],[],{"title":49,"description":50},[],"03_add_client_sdk",{"id":65,"data":67,"body":73,"filePath":74,"digest":75,"rendered":76},{"title":68,"description":69,"editUrl":16,"head":70,"template":32,"sidebar":71,"pagefind":16,"draft":22},"Add Client SDK","Add Vonage Client SDK to index.html",[],{"hidden":22,"attrs":72},{},"We'll be creating a WebXR application using \u003Ca href=\"https://xrblocks.github.io\" target=\"_blank\">XR Blocks\u003C/a> that can answer phone calls.\n\nThe following code will be placed in the `index.html` file.\n\nFirst, we will need to load the Vonage Client SDK from a CDN (`\u003C!-- ⌄⌄⌄ Load the Vonage Client SDK ⌄⌄⌄ -->`):\n```html\n\u003Cscript src=\"https://cdn.jsdelivr.net/npm/@vonage/client-sdk@latest/dist/vonageClientSDK.min.js\">\u003C/script>\n```\n\n> Note: You can also install the Client SDK and point to the nodes module folder if you are using a bundler.\n\n## That's it for the HTML!\n\nEverything else will be handled by XR Blocks.","src/content/docs/03_Add_Client_SDK.md","77c79f191f661eb3",{"html":77,"metadata":78},"\u003Cp>We’ll be creating a WebXR application using \u003Ca href=\"https://xrblocks.github.io\" target=\"_blank\">XR Blocks\u003C/a> that can answer phone calls.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">index.html\u003C/code> file.\u003C/p>\n\u003Cp>First, we will need to load the Vonage Client SDK from a CDN (\u003Ccode dir=\"auto\"><!-- ⌄⌄⌄ Load the Vonage Client SDK ⌄⌄⌄ -->\u003C/code>):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">script\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">src\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://cdn.jsdelivr.net/npm/@vonage/client-sdk@latest/dist/vonageClientSDK.min.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\">></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">script\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript src="https://cdn.jsdelivr.net/npm/@vonage/client-sdk@latest/dist/vonageClientSDK.min.js">\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Note: You can also install the Client SDK and point to the nodes module folder if you are using a bundler.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"thats-it-for-the-html\">That’s it for the HTML!\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#thats-it-for-the-html\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “That’s it for the HTML!”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Everything else will be handled by XR Blocks.\u003C/p>",{"headings":79,"localImagePaths":84,"remoteImagePaths":85,"frontmatter":86,"imagePaths":87},[80],{"depth":81,"slug":82,"text":83},2,"thats-it-for-the-html","That’s it for the HTML!",[],[],{"title":68,"description":69},[],"04_vonage_call_panel",{"id":88,"data":90,"body":96,"filePath":97,"digest":98,"rendered":99},{"title":91,"description":92,"editUrl":16,"head":93,"template":32,"sidebar":94,"pagefind":16,"draft":22},"Vonage Call Panel","Create XR Blocks UI to answer phone calls",[],{"hidden":22,"attrs":95},{},"We'll be creating the UI to recieve phone calls via the Vonage Voice API using the XR Blocks library's \u003Ca href=\"https://xrblocks.github.io/docs/api/classes/SpatialPanel/\" target=\"_blank\">SpatialPanel Class\u003C/a>.\n\nThe following code will be placed in the `VonageAudioCall.js` file.\n\nFirst, let's initiate the constructor for our panel with some variables:\n`// ⌄⌄⌄ Create constructor ⌄⌄⌄`\n```js\nconstructor() {\n super();\n this.token = '';\n this.client = new vonageClientSDK.VonageClient();\n this.callId = null;\n // Keep a reference to the panel so we can destroy it later\n this.panel = null; \n this.statusText = null;\n this.userName = \"XR_User_1\";\n this.grid = null;\n this.controlRow = null;\n}\n```\n\nHere's the function to create the panel:\n`// ⌄⌄⌄ Create call panel ⌄⌄⌄`\n```js\ncreateCallPanel(callerName) {\n // SAFETY: If a panel already exists, don't create another one.\n if (this.panel) return;\n\n console.log(\"Creating Call UI...\");\n \n // 1. Create the Panel\n this.panel = new xb.SpatialPanel({ backgroundColor: '#2b2b2baa' });\n this.panel.position.set(\n 0,\n xb.user.height - 0.5,\n -xb.user.objectDistance\n );\n\n this.add(this.panel);\n\n this.grid = this.panel.addGrid();\n\n // 2. Status Text\n this.statusText = this.grid.addRow({ weight: 0.7 }).addText({\n text: `Incoming call from ${callerName}...`,\n fontColor: '#ffffff',\n fontSize: 0.08,\n });\n\n this.updateControlRow('INCOMING');\n}\n```\n\nFunction to update the call control section:\n`// ⌄⌄⌄ Update call controls ⌄⌄⌄`\n```js\nupdateControlRow(state) {\n if (!this.grid) return;\n\n // 1. Remove the existing row if it exists\n if (this.controlRow) {\n this.grid.remove(this.controlRow);\n this.controlRow = null;\n this.grid.resetLayout();\n }\n\n // 2. Create a fresh row. It will naturally append below the Status Text.\n // We give it the full remaining weight (0.3 relative to the panel, or flexible)\n this.controlRow = this.grid.addRow({ weight: 0.3 });\n\n if (state === 'INCOMING') {\n // --- ANSWER BUTTON ---\n const answerBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({\n text: 'call',\n fontSize: 0.5,\n backgroundColor: '#00ff00'\n });\n answerBtn.onTriggered = () => this._onAnswer();\n\n // --- REJECT BUTTON ---\n const rejectBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({\n text: 'call_end',\n fontSize: 0.5,\n backgroundColor: '#ff0000'\n });\n rejectBtn.onTriggered = () => this._onReject();\n\n } else if (state === 'CONNECTED') {\n // --- HANGUP BUTTON ---\n // This is a fresh row, so layouts will calculate correctly\n const hangupBtn = this.controlRow.addCol({ weight: 1 }).addIconButton({\n text: 'call_end',\n fontSize: 0.5,\n backgroundColor: '#ff0000'\n });\n hangupBtn.onTriggered = () => this._onHangup();\n }\n\n // 3. Force layout update\n this.panel.updateLayouts();\n}\n```\n\nThis function will remove the panel once the call is over:\n`// ⌄⌄⌄ Remove call panel ⌄⌄⌄`\n```js\nremoveCallPanel() {\n if (this.panel) {\n console.log(\"Destroying Call UI...\");\n this.remove(this.panel);\n this.panel = null;\n this.grid = null;\n this.statusText = null;\n this.controlRow = null;\n }\n}\n```\n\nThis function answers the call and updates the status and call control section:\n`// ⌄⌄⌄ Answer call method ⌄⌄⌄`\n```js\n_onAnswer() {\n console.log('Answering...');\n this.client.answer(this.callId)\n .then(() => {\n console.log(\"Success answering call.\");\n this.statusText.text = `Call answered.`;\n this.updateControlRow('CONNECTED');\n })\n .catch(error => {\n console.error(\"Error answering call: \", error);\n }); \n}\n```\n\nThis function will reject the incoming call and remove the panel:\n`// ⌄⌄⌄ Reject call method ⌄⌄⌄`\n```js\n_onReject() {\n console.log('Rejecting...');\n this.client.reject(this.callId)\n .then(() => {\n console.log(\"Success rejecting call.\");\n })\n .catch(error => {\n console.error(\"Error rejecting call: \", error);\n }); \n // We manually destroy the panel here too, just in case the event lags\n this.removeCallPanel(); \n}\n```\n\nThis function will hang up the ongoing call and remove the panel:\n`// ⌄⌄⌄ Hang Up call method ⌄⌄⌄ `\n```js\n_onHangup() {\n console.log('Hanging up...');\n this.client.hangup(this.callId)\n .then(() => {\n console.log(\"Success hanging up call.\");\n })\n .catch(error => {\n console.error(\"Error hanging up call: \", error);\n }); \n // We manually destroy the panel here too, just in case the event lags\n this.removeCallPanel(); \n}\n```\n\nSet up some listeners for the events that the Vonage Client SDK will emit and what to do:\n`// ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄`\n```js\nsetupVonageListeners() {\n // --- CREATE UI ON INVITE ---\n this.client.on('callInvite', (callId, from, channelType) => {\n this.callId = callId;\n const maskedNumber = from.replace(/\\d(?=(?:\\D*\\d){4})/g, \"*\")\n console.log(`Incoming call from ${maskedNumber}`);\n \n // Trigger the UI creation here\n this.createCallPanel(maskedNumber);\n });\n\n this.client.on('legStatusUpdate', (callId, legId, status) => {\n console.log(\"status: \", status);\n if (this.statusText) {\n this.statusText.text = `Status: ${status}`;\n }\n });\n\n // --- REMOVE UI ON CANCEL/HANGUP ---\n this.client.on('callInviteCancel', (callId) => {\n console.log(`Call cancelled: ${callId}`);\n this.callId = null;\n this.removeCallPanel();\n });\n\n this.client.on(\"callHangup\", (callId, callQuality, reason) => {\n console.log(`Call hung up: ${reason}`);\n this.callId = null;\n this.removeCallPanel();\n });\n}\n```\n\nGet a token from the server so you can connect to a session:\n`// ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ `\n```js\nasync connectToVonage(name) {\n try {\n console.log(`Fetching token for ${name}...`);\n\n // 1. Fetch the token (AWAIT the result)\n const response = await fetch(`/token?name=${name}`);\n \n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data = await response.json();\n this.token = data.token;\n console.log(\"Fetched token successfully.\");\n\n // 2. Create the Session (AWAIT the result)\n const sessionId = await this.client.createSession(this.token);\n \n console.log(\"Session created successfully. Session ID:\", sessionId);\n\n // 3. Update UI\n // Instead, update your XR Panel text to show we are ready\n if(this.statusText) {\n this.statusText.text = \"Connected. Waiting for calls...\";\n }\n\n } catch (error) {\n console.error(\"Connection failed:\", error);\n if(this.statusText) this.statusText.text = \"Connection Failed.\";\n }\n}\n```\n\nInitialize the Class when loaded into the page:\n`// ⌄⌄⌄ Initialize ⌄⌄⌄`\n```js\ninit() {\n console.log(\"Vonage init!\",this.client);\n this.setupVonageListeners();\n this.connectToVonage(this.userName);\n}\n```","src/content/docs/04_Vonage_Call_Panel.md","b1135949c5400620",{"html":100,"metadata":101},"\u003Cp>We’ll be creating the UI to recieve phone calls via the Vonage Voice API using the XR Blocks library’s \u003Ca href=\"https://xrblocks.github.io/docs/api/classes/SpatialPanel/\" target=\"_blank\">SpatialPanel Class\u003C/a>.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">VonageAudioCall.js\u003C/code> file.\u003C/p>\n\u003Cp>First, let’s initiate the constructor for our panel with some variables:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create constructor ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">constructor\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">super\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">vonageClientSDK\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">VonageClient\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Keep a reference to the panel so we can destroy it later\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">userName\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">XR_User_1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"constructor() { super(); this.token = ''; this.client = new vonageClientSDK.VonageClient(); this.callId = null; // Keep a reference to the panel so we can destroy it later this.panel = null; this.statusText = null; this.userName = "XR_User_1"; this.grid = null; this.controlRow = null;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Here’s the function to create the panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create call panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createCallPanel\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">callerName\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// SAFETY: If a panel already exists, don't create another one.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Creating Call UI...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Create the Panel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">SpatialPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#2b2b2baa\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">objectDistance\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addGrid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Status Text\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.7\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Incoming call from \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">callerName\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ffffff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.08\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateControlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">INCOMING\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"createCallPanel(callerName) { // SAFETY: If a panel already exists, don't create another one. if (this.panel) return; console.log("Creating Call UI..."); // 1. Create the Panel this.panel = new xb.SpatialPanel({ backgroundColor: '#2b2b2baa' }); this.panel.position.set( 0, xb.user.height - 0.5, -xb.user.objectDistance ); this.add(this.panel); this.grid = this.panel.addGrid(); // 2. Status Text this.statusText = this.grid.addRow({ weight: 0.7 }).addText({ text: `Incoming call from ${callerName}...`, fontColor: '#ffffff', fontSize: 0.08, }); this.updateControlRow('INCOMING');}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Function to update the call control section:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Update call controls ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateControlRow\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">state\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Remove the existing row if it exists\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">resetLayout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Create a fresh row. It will naturally append below the Status Text.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// We give it the full remaining weight (0.3 relative to the panel, or flexible)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.3\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">state\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">INCOMING\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- ANSWER BUTTON ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">answerBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">controlRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">call\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#00ff00\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">answerBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onAnswer\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- REJECT BUTTON ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">rejectBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">controlRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">call_end\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ff0000\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">rejectBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onReject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">else\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">state\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">CONNECTED\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- HANGUP BUTTON ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// This is a fresh row, so layouts will calculate correctly\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hangupBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">controlRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">call_end\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ff0000\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">hangupBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onHangup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 3. Force layout update\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateLayouts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"updateControlRow(state) { if (!this.grid) return; // 1. Remove the existing row if it exists if (this.controlRow) { this.grid.remove(this.controlRow); this.controlRow = null; this.grid.resetLayout(); } // 2. Create a fresh row. It will naturally append below the Status Text. // We give it the full remaining weight (0.3 relative to the panel, or flexible) this.controlRow = this.grid.addRow({ weight: 0.3 }); if (state === 'INCOMING') { // --- ANSWER BUTTON --- const answerBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({ text: 'call', fontSize: 0.5, backgroundColor: '#00ff00' }); answerBtn.onTriggered = () => this._onAnswer(); // --- REJECT BUTTON --- const rejectBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({ text: 'call_end', fontSize: 0.5, backgroundColor: '#ff0000' }); rejectBtn.onTriggered = () => this._onReject(); } else if (state === 'CONNECTED') { // --- HANGUP BUTTON --- // This is a fresh row, so layouts will calculate correctly const hangupBtn = this.controlRow.addCol({ weight: 1 }).addIconButton({ text: 'call_end', fontSize: 0.5, backgroundColor: '#ff0000' }); hangupBtn.onTriggered = () => this._onHangup(); } // 3. Force layout update this.panel.updateLayouts();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will remove the panel once the call is over:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Remove call panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Destroying Call UI...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"removeCallPanel() { if (this.panel) { console.log("Destroying Call UI..."); this.remove(this.panel); this.panel = null; this.grid = null; this.statusText = null; this.controlRow = null; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function answers the call and updates the status and call control section:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Answer call method ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onAnswer\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Answering...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">answer\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Success answering call.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Call answered.\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateControlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">CONNECTED\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Error answering call: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_onAnswer() { console.log('Answering...'); this.client.answer(this.callId) .then(() => { console.log("Success answering call."); this.statusText.text = `Call answered.`; this.updateControlRow('CONNECTED'); }) .catch(error => { console.error("Error answering call: ", error); });}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will reject the incoming call and remove the panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Reject call method ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onReject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Rejecting...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">reject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Success rejecting call.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Error rejecting call: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// We manually destroy the panel here too, just in case the event lags\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_onReject() { console.log('Rejecting...'); this.client.reject(this.callId) .then(() => { console.log("Success rejecting call."); }) .catch(error => { console.error("Error rejecting call: ", error); }); // We manually destroy the panel here too, just in case the event lags this.removeCallPanel();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will hang up the ongoing call and remove the panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Hang Up call method ⌄⌄⌄ \u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onHangup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Hanging up...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hangup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Success hanging up call.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Error hanging up call: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// We manually destroy the panel here too, just in case the event lags\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_onHangup() { console.log('Hanging up...'); this.client.hangup(this.callId) .then(() => { console.log("Success hanging up call."); }) .catch(error => { console.error("Error hanging up call: ", error); }); // We manually destroy the panel here too, just in case the event lags this.removeCallPanel();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Set up some listeners for the events that the Vonage Client SDK will emit and what to do:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setupVonageListeners\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- CREATE UI ON INVITE ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">callInvite\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">channelType\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">;\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">maskedNumber\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">from\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">replace\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">/\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">\\d\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">(?=(?:\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">\\D\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">\\d\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">{4}\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">)\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">/\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">g\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">*\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Incoming call from \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">maskedNumber\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Trigger the UI creation here\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createCallPanel\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">maskedNumber\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">legStatusUpdate\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">legId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">status\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">status: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">status\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Status: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">status\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- REMOVE UI ON CANCEL/HANGUP ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">callInviteCancel\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">callId\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Call cancelled: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">callId\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">callHangup\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">callQuality\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">reason\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Call hung up: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">reason\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"setupVonageListeners() { // --- CREATE UI ON INVITE --- this.client.on('callInvite', (callId, from, channelType) => { this.callId = callId; const maskedNumber = from.replace(/\\d(?=(?:\\D*\\d){4})/g, "*") console.log(`Incoming call from ${maskedNumber}`); // Trigger the UI creation here this.createCallPanel(maskedNumber); }); this.client.on('legStatusUpdate', (callId, legId, status) => { console.log("status: ", status); if (this.statusText) { this.statusText.text = `Status: ${status}`; } }); // --- REMOVE UI ON CANCEL/HANGUP --- this.client.on('callInviteCancel', (callId) => { console.log(`Call cancelled: ${callId}`); this.callId = null; this.removeCallPanel(); }); this.client.on("callHangup", (callId, callQuality, reason) => { console.log(`Call hung up: ${reason}`); this.callId = null; this.removeCallPanel(); });}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Get a token from the server so you can connect to a session:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ \u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">async\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">connectToVonage\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">name\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">try\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Fetching token for \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">name\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Fetch the token (AWAIT the result)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fetch\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">/token?name=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">name\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">ok\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">throw\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">HTTP error! status: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">status\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">json\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Fetched token successfully.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Create the Session (AWAIT the result)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sessionId\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createSession\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Session created successfully. Session ID:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">sessionId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 3. Update UI\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Instead, update your XR Panel text to show we are ready\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Connected. Waiting for calls...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Connection failed:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Connection Failed.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"async connectToVonage(name) { try { console.log(`Fetching token for ${name}...`); // 1. Fetch the token (AWAIT the result) const response = await fetch(`/token?name=${name}`); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); this.token = data.token; console.log("Fetched token successfully."); // 2. Create the Session (AWAIT the result) const sessionId = await this.client.createSession(this.token); console.log("Session created successfully. Session ID:", sessionId); // 3. Update UI // Instead, update your XR Panel text to show we are ready if(this.statusText) { this.statusText.text = "Connected. Waiting for calls..."; } } catch (error) { console.error("Connection failed:", error); if(this.statusText) this.statusText.text = "Connection Failed."; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Initialize the Class when loaded into the page:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Initialize ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">init\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Vonage init!\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setupVonageListeners\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">connectToVonage\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">userName\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"init() { console.log("Vonage init!",this.client); this.setupVonageListeners(); this.connectToVonage(this.userName);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":102,"localImagePaths":103,"remoteImagePaths":104,"frontmatter":105,"imagePaths":106},[],[],[],{"title":91,"description":92},[],"05_exit_button",{"id":107,"data":109,"body":115,"filePath":116,"digest":117,"rendered":118},{"title":110,"description":111,"editUrl":16,"head":112,"template":32,"sidebar":113,"pagefind":16,"draft":22},"Exiting WebXR application","Button to exit WebXR application",[],{"hidden":22,"attrs":114},{},"When in the WebXR environment using a headset, I could not figure out how to leave the experience, so I made an Exit Demo Panel.\n\nThe following code will be placed in the `ExitButton.js` file.\n\nCreate the constructor for the Class:\n`// ⌄⌄⌄ Create constructor ⌄⌄⌄`\n```js\n constructor() {\n super();\n // Keep a reference to the panel so we can destroy it later\n this.panel = null; \n this.statusText = null;\n this.exitPanelText = \"Exit Demo\";\n }\n```\n\nFunction to create a panel for the Exit Button:\n`// ⌄⌄⌄ Create Exit Button panel ⌄⌄⌄`\n```js\n createExitPanel() {\n // SAFETY: If a panel already exists, don't create another one.\n if (this.panel) return;\n\n console.log(\"Creating Exit Button...\");\n \n // 1. Create the Panel\n this.panel = new xb.SpatialPanel({\n width: 0.5,\n height: 0.5, \n backgroundColor: '#2b2b2baa'\n });\n\n this.panel.position.set(\n 0,\n xb.user.height,\n 2.0\n );\n\n this.panel.rotation.set(0, Math.PI, 0);\n this.add(this.panel);\n\n const grid = this.panel.addGrid();\n\n // 2. Status Text\n this.statusText = grid.addRow({ weight: 1 }).addText({\n text: this.exitPanelText,\n fontColor: '#ffffff',\n fontSize: .4,\n });\n\n // Orbiter\n const orbiter = grid.addOrbiter();\n orbiter.addExitButton();\n this.panel.updateLayouts();\n }\n```\n\nInitialize Class when loaded into the page:\n`// ⌄⌄⌄ Initialize ⌄⌄⌄`\n```js\n init() {\n console.log(\"Exit Button init!\",this.client);\n this.createExitPanel();\n }\n```","src/content/docs/05_Exit_Button.md","8a1b55e67864fa9e",{"html":119,"metadata":120},"\u003Cp>When in the WebXR environment using a headset, I could not figure out how to leave the experience, so I made an Exit Demo Panel.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">ExitButton.js\u003C/code> file.\u003C/p>\n\u003Cp>Create the constructor for the Class:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create constructor ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">constructor\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">super\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Keep a reference to the panel so we can destroy it later\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">exitPanelText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Exit Demo\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" constructor() { super(); // Keep a reference to the panel so we can destroy it later this.panel = null; this.statusText = null; this.exitPanelText = "Exit Demo"; }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Function to create a panel for the Exit Button:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create Exit Button panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createExitPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// SAFETY: If a panel already exists, don't create another one.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Creating Exit Button...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Create the Panel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">SpatialPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">width: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">height: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#2b2b2baa\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2.0\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">rotation\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">Math\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">PI\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addGrid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Status Text\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">exitPanelText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ffffff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">.4\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Orbiter\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">orbiter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addOrbiter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">orbiter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addExitButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateLayouts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" createExitPanel() { // SAFETY: If a panel already exists, don't create another one. if (this.panel) return; console.log("Creating Exit Button..."); // 1. Create the Panel this.panel = new xb.SpatialPanel({ width: 0.5, height: 0.5, backgroundColor: '#2b2b2baa' }); this.panel.position.set( 0, xb.user.height, 2.0 ); this.panel.rotation.set(0, Math.PI, 0); this.add(this.panel); const grid = this.panel.addGrid(); // 2. Status Text this.statusText = grid.addRow({ weight: 1 }).addText({ text: this.exitPanelText, fontColor: '#ffffff', fontSize: .4, }); // Orbiter const orbiter = grid.addOrbiter(); orbiter.addExitButton(); this.panel.updateLayouts(); }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Initialize Class when loaded into the page:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Initialize ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">init\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Exit Button init!\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createExitPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" init() { console.log("Exit Button init!",this.client); this.createExitPanel(); }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":121,"localImagePaths":122,"remoteImagePaths":123,"frontmatter":124,"imagePaths":125},[],[],[],{"title":110,"description":111},[],"06_add_to_xr_blocks",{"id":126,"data":128,"body":134,"filePath":135,"digest":136,"rendered":137},{"title":129,"description":130,"editUrl":16,"head":131,"template":32,"sidebar":132,"pagefind":16,"draft":22},"Add panels to XR Blocks","adding panels to WebXR application",[],{"hidden":22,"attrs":133},{},"Let's add the 2 panels to the application.\n\nThe following code will be placed in the `main.js` file.\n\nFirst, import the Panels:\n`// ⌄⌄⌄ import Vonage Call Panel and Exit Button ⌄⌄⌄`\n```js\nimport { VonageAudioCall } from './VonageAudioCall.js';\nimport { ExitPanel } from './ExitButton.js';\n```\n\nCreate instances and add to the application:\n`// ⌄⌄⌄ add Vonage Call Panel and Exit Button ⌄⌄⌄`\n```js\nxb.add(new VonageAudioCall());\nxb.add(new ExitPanel());\n```\n\n## Time to test the application\nRefresh the application and try to call the phone number that was purchased and assigned while running the setup script.\n\n> Note: You can find the phone number connected to your Vonage application in the `.env` file.","src/content/docs/06_Add_To_XR_Blocks.md","d3b20f81f928d1fb",{"html":138,"metadata":139},"\u003Cp>Let’s add the 2 panels to the application.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">main.js\u003C/code> file.\u003C/p>\n\u003Cp>First, import the Panels:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ import Vonage Call Panel and Exit Button ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { VonageAudioCall } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./VonageAudioCall.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { ExitPanel } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./ExitButton.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { VonageAudioCall } from './VonageAudioCall.js';import { ExitPanel } from './ExitButton.js';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Create instances and add to the application:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ add Vonage Call Panel and Exit Button ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">VonageAudioCall\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">());\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">ExitPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">());\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"xb.add(new VonageAudioCall());xb.add(new ExitPanel());\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"time-to-test-the-application\">Time to test the application\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#time-to-test-the-application\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “Time to test the application”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Refresh the application and try to call the phone number that was purchased and assigned while running the setup script.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Note: You can find the phone number connected to your Vonage application in the \u003Ccode dir=\"auto\">.env\u003C/code> file.\u003C/p>\n\u003C/blockquote>",{"headings":140,"localImagePaths":144,"remoteImagePaths":145,"frontmatter":146,"imagePaths":147},[141],{"depth":81,"slug":142,"text":143},"time-to-test-the-application","Time to test the application",[],[],{"title":129,"description":130},[],"07_congrats",{"id":148,"data":150,"body":156,"filePath":157,"digest":158,"rendered":159},{"title":151,"description":152,"editUrl":16,"head":153,"template":32,"sidebar":154,"pagefind":16,"draft":22},"Congratulations!","What's next.",[],{"hidden":22,"attrs":155},{},"## You did it!\n\nYou now have a WebXR application using XR Blocks and the Vonage Voice API that can receive phone calls.\n\n## What's Next?\n- Can you create a WebXR application that makes phone calls? How about a voice chat in a WebXR environment?\n- Learn more about the Vonage Voice API in our \u003Ca href=\"https://developer.vonage.com/en/voice/voice-api/overview\" target=\"_blank\">developer documenation\u003C/a>\n- Connect with us on \u003Ca href=\"https://x.com/vonagedev\" target=\"_blank\">Twitter / X\u003C/a> and \u003Ca href=\"https://www.linkedin.com/company/vonage-dev\" target=\"_blank\">LinkedIn\u003C/a>\n- Join our \u003Ca href=\"https://vonage.dev/slack\" target=\"_blank\">Developer Community Slack channel\u003C/a> to connect with others building with Vonage","src/content/docs/07_Congrats.md","8c617d22f873e7d6",{"html":160,"metadata":161},"\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"you-did-it\">You did it!\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#you-did-it\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “You did it!”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>You now have a WebXR application using XR Blocks and the Vonage Voice API that can receive phone calls.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"whats-next\">What’s Next?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#whats-next\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “What’s Next?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Can you create a WebXR application that makes phone calls? How about a voice chat in a WebXR environment?\u003C/li>\n\u003Cli>Learn more about the Vonage Voice API in our \u003Ca href=\"https://developer.vonage.com/en/voice/voice-api/overview\" target=\"_blank\">developer documenation\u003C/a>\u003C/li>\n\u003Cli>Connect with us on \u003Ca href=\"https://x.com/vonagedev\" target=\"_blank\">Twitter / X\u003C/a> and \u003Ca href=\"https://www.linkedin.com/company/vonage-dev\" target=\"_blank\">LinkedIn\u003C/a>\u003C/li>\n\u003Cli>Join our \u003Ca href=\"https://vonage.dev/slack\" target=\"_blank\">Developer Community Slack channel\u003C/a> to connect with others building with Vonage\u003C/li>\n\u003C/ul>",{"headings":162,"localImagePaths":169,"remoteImagePaths":170,"frontmatter":171,"imagePaths":172},[163,166],{"depth":81,"slug":164,"text":165},"you-did-it","You did it!",{"depth":81,"slug":167,"text":168},"whats-next","What’s Next?",[],[],{"title":151,"description":152},[]] \ No newline at end of file +[["Map",1,2,9,10],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.18.1","content-config-digest","a30a942a2ceda2e1","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"where\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true,\"allowedHosts\":[]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[],\"remotePatterns\":[],\"responsiveStyles\":false},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":false,\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[null,null,null],\"rehypePlugins\":[[null,{\"experimentalHeadingIdCompat\":false}],null,[null,{\"themes\":[{\"name\":\"Night Owl No Italics\",\"type\":\"dark\",\"colors\":{\"focusBorder\":\"#122d42\",\"foreground\":\"#d6deeb\",\"disabledForeground\":\"#cccccc80\",\"descriptionForeground\":\"#d6deebb3\",\"errorForeground\":\"#ef5350\",\"icon.foreground\":\"#c5c5c5\",\"contrastActiveBorder\":null,\"contrastBorder\":\"#122d42\",\"textBlockQuote.background\":\"#7f7f7f1a\",\"textBlockQuote.border\":\"#007acc80\",\"textCodeBlock.background\":\"#4f4f4f\",\"textLink.activeForeground\":\"#3794ff\",\"textLink.foreground\":\"#3794ff\",\"textPreformat.foreground\":\"#d7ba7d\",\"textSeparator.foreground\":\"#ffffff2e\",\"editor.background\":\"#23262f\",\"editor.foreground\":\"#d6deeb\",\"editorLineNumber.foreground\":\"#4b6479\",\"editorLineNumber.activeForeground\":\"#c5e4fd\",\"editorActiveLineNumber.foreground\":\"#c6c6c6\",\"editor.selectionBackground\":\"#1d3b53\",\"editor.inactiveSelectionBackground\":\"#7e57c25a\",\"editor.selectionHighlightBackground\":\"#5f7e9779\",\"editorError.foreground\":\"#ef5350\",\"editorWarning.foreground\":\"#b39554\",\"editorInfo.foreground\":\"#3794ff\",\"editorHint.foreground\":\"#eeeeeeb2\",\"problemsErrorIcon.foreground\":\"#ef5350\",\"problemsWarningIcon.foreground\":\"#b39554\",\"problemsInfoIcon.foreground\":\"#3794ff\",\"editor.findMatchBackground\":\"#5f7e9779\",\"editor.findMatchHighlightBackground\":\"#1085bb5d\",\"editor.findRangeHighlightBackground\":\"#3a3d4166\",\"editorLink.activeForeground\":\"#4e94ce\",\"editorLightBulb.foreground\":\"#ffcc00\",\"editorLightBulbAutoFix.foreground\":\"#75beff\",\"diffEditor.insertedTextBackground\":\"#99b76d23\",\"diffEditor.insertedTextBorder\":\"#c5e47833\",\"diffEditor.removedTextBackground\":\"#ef535033\",\"diffEditor.removedTextBorder\":\"#ef53504d\",\"diffEditor.insertedLineBackground\":\"#9bb95533\",\"diffEditor.removedLineBackground\":\"#ff000033\",\"editorStickyScroll.background\":\"#011627\",\"editorStickyScrollHover.background\":\"#2a2d2e\",\"editorInlayHint.background\":\"#5f7e97cc\",\"editorInlayHint.foreground\":\"#ffffff\",\"editorInlayHint.typeBackground\":\"#5f7e97cc\",\"editorInlayHint.typeForeground\":\"#ffffff\",\"editorInlayHint.parameterBackground\":\"#5f7e97cc\",\"editorInlayHint.parameterForeground\":\"#ffffff\",\"editorPane.background\":\"#011627\",\"editorGroup.emptyBackground\":\"#011627\",\"editorGroup.focusedEmptyBorder\":null,\"editorGroupHeader.tabsBackground\":\"var(--sl-color-black)\",\"editorGroupHeader.tabsBorder\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"editorGroupHeader.noTabsBackground\":\"#011627\",\"editorGroupHeader.border\":null,\"editorGroup.border\":\"#011627\",\"editorGroup.dropBackground\":\"#7e57c273\",\"editorGroup.dropIntoPromptForeground\":\"#d6deeb\",\"editorGroup.dropIntoPromptBackground\":\"#021320\",\"editorGroup.dropIntoPromptBorder\":null,\"sideBySideEditor.horizontalBorder\":\"#011627\",\"sideBySideEditor.verticalBorder\":\"#011627\",\"scrollbar.shadow\":\"#010b14\",\"scrollbarSlider.background\":\"#ffffff17\",\"scrollbarSlider.hoverBackground\":\"#ffffff40\",\"scrollbarSlider.activeBackground\":\"#084d8180\",\"panel.background\":\"#011627\",\"panel.border\":\"#5f7e97\",\"panelTitle.activeBorder\":\"#5f7e97\",\"panelTitle.activeForeground\":\"#ffffffcc\",\"panelTitle.inactiveForeground\":\"#d6deeb80\",\"panelSectionHeader.background\":\"#80808051\",\"terminal.background\":\"#011627\",\"widget.shadow\":\"#011627\",\"editorWidget.background\":\"#021320\",\"editorWidget.foreground\":\"#d6deeb\",\"editorWidget.border\":\"#5f7e97\",\"quickInput.background\":\"#021320\",\"quickInput.foreground\":\"#d6deeb\",\"quickInputTitle.background\":\"#ffffff1a\",\"pickerGroup.foreground\":\"#d1aaff\",\"pickerGroup.border\":\"#011627\",\"editor.hoverHighlightBackground\":\"#7e57c25a\",\"editorHoverWidget.background\":\"#011627\",\"editorHoverWidget.foreground\":\"#d6deeb\",\"editorHoverWidget.border\":\"#5f7e97\",\"editorHoverWidget.statusBarBackground\":\"#011a2f\",\"titleBar.activeBackground\":\"var(--sl-color-black)\",\"titleBar.activeForeground\":\"var(--sl-color-text)\",\"titleBar.inactiveBackground\":\"#010e1a\",\"titleBar.inactiveForeground\":\"#eeefff99\",\"titleBar.border\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"toolbar.hoverBackground\":\"#5a5d5e50\",\"toolbar.activeBackground\":\"#63666750\",\"tab.activeBackground\":\"#0b2942\",\"tab.unfocusedActiveBackground\":\"#0b2942\",\"tab.inactiveBackground\":\"#01111d\",\"tab.unfocusedInactiveBackground\":\"#01111d\",\"tab.activeForeground\":\"var(--sl-color-text)\",\"tab.inactiveForeground\":\"#5f7e97\",\"tab.unfocusedActiveForeground\":\"#5f7e97\",\"tab.unfocusedInactiveForeground\":\"#5f7e97\",\"tab.hoverBackground\":null,\"tab.unfocusedHoverBackground\":null,\"tab.hoverForeground\":null,\"tab.unfocusedHoverForeground\":null,\"tab.border\":\"#272b3b\",\"tab.lastPinnedBorder\":\"#585858\",\"tab.activeBorder\":\"transparent\",\"tab.unfocusedActiveBorder\":\"#262a39\",\"tab.activeBorderTop\":\"var(--sl-color-accent-high)\",\"tab.unfocusedActiveBorderTop\":null,\"tab.hoverBorder\":null,\"tab.unfocusedHoverBorder\":null,\"tab.activeModifiedBorder\":\"#3399cc\",\"tab.inactiveModifiedBorder\":\"#3399cc80\",\"tab.unfocusedActiveModifiedBorder\":\"#3399cc80\",\"tab.unfocusedInactiveModifiedBorder\":\"#3399cc40\",\"badge.background\":\"#5f7e97\",\"badge.foreground\":\"#ffffff\",\"button.background\":\"#7e57c2cc\",\"button.foreground\":\"#ffffffcc\",\"button.border\":\"#122d42\",\"button.separator\":\"#ffffff52\",\"button.hoverBackground\":\"#7e57c2\",\"button.secondaryBackground\":\"#3a3d41\",\"button.secondaryForeground\":\"#ffffff\",\"button.secondaryHoverBackground\":\"#46494e\",\"dropdown.background\":\"#011627\",\"dropdown.foreground\":\"#ffffffcc\",\"dropdown.border\":\"#5f7e97\",\"list.activeSelectionBackground\":\"#234d708c\",\"list.activeSelectionForeground\":\"#ffffff\",\"tree.indentGuidesStroke\":\"#585858\",\"input.background\":\"#0b253a\",\"input.foreground\":\"#ffffffcc\",\"input.placeholderForeground\":\"#5f7e97\",\"inputOption.activeBorder\":\"#ffffffcc\",\"inputOption.hoverBackground\":\"#5a5d5e80\",\"inputOption.activeBackground\":\"#122d4266\",\"inputOption.activeForeground\":\"#ffffff\",\"inputValidation.infoBackground\":\"#00589ef2\",\"inputValidation.infoBorder\":\"#64b5f6\",\"inputValidation.warningBackground\":\"#675700f2\",\"inputValidation.warningBorder\":\"#ffca28\",\"inputValidation.errorBackground\":\"#ab0300f2\",\"inputValidation.errorBorder\":\"#ef5350\",\"keybindingLabel.background\":\"#8080802b\",\"keybindingLabel.foreground\":\"#cccccc\",\"keybindingLabel.border\":\"#33333399\",\"keybindingLabel.bottomBorder\":\"#44444499\",\"menu.foreground\":\"#ffffffcc\",\"menu.background\":\"#011627\",\"menu.selectionForeground\":\"#ffffff\",\"menu.selectionBackground\":\"#234d708c\",\"menu.separatorBackground\":\"#606060\",\"editor.snippetTabstopHighlightBackground\":\"#7c7c74c\",\"editor.snippetFinalTabstopHighlightBorder\":\"#525252\",\"terminal.ansiBlack\":\"#011627\",\"terminal.ansiRed\":\"#ef5350\",\"terminal.ansiGreen\":\"#22da6e\",\"terminal.ansiYellow\":\"#c5e478\",\"terminal.ansiBlue\":\"#82aaff\",\"terminal.ansiMagenta\":\"#c792ea\",\"terminal.ansiCyan\":\"#21c7a8\",\"terminal.ansiWhite\":\"#ffffff\",\"terminal.ansiBrightBlack\":\"#575656\",\"terminal.ansiBrightRed\":\"#ef5350\",\"terminal.ansiBrightGreen\":\"#22da6e\",\"terminal.ansiBrightYellow\":\"#ffeb95\",\"terminal.ansiBrightBlue\":\"#82aaff\",\"terminal.ansiBrightMagenta\":\"#c792ea\",\"terminal.ansiBrightCyan\":\"#7fdbca\",\"terminal.ansiBrightWhite\":\"#ffffff\",\"selection.background\":\"#4373c2\",\"input.border\":\"#5f7e97\",\"punctuation.definition.generic.begin.html\":\"#ef5350f2\",\"progress.background\":\"#7e57c2\",\"breadcrumb.foreground\":\"#a599e9\",\"breadcrumb.focusForeground\":\"#ffffff\",\"breadcrumb.activeSelectionForeground\":\"#ffffff\",\"breadcrumbPicker.background\":\"#001122\",\"list.invalidItemForeground\":\"#975f94\",\"list.dropBackground\":\"#011627\",\"list.focusBackground\":\"#010d18\",\"list.focusForeground\":\"#ffffff\",\"list.highlightForeground\":\"#ffffff\",\"list.hoverBackground\":\"#011627\",\"list.hoverForeground\":\"#ffffff\",\"list.inactiveSelectionBackground\":\"#0e293f\",\"list.inactiveSelectionForeground\":\"#5f7e97\",\"activityBar.background\":\"#011627\",\"activityBar.dropBackground\":\"#5f7e97\",\"activityBar.foreground\":\"#5f7e97\",\"activityBar.border\":\"#011627\",\"activityBarBadge.background\":\"#44596b\",\"activityBarBadge.foreground\":\"#ffffff\",\"sideBar.background\":\"#011627\",\"sideBar.foreground\":\"#89a4bb\",\"sideBar.border\":\"#011627\",\"sideBarTitle.foreground\":\"#5f7e97\",\"sideBarSectionHeader.background\":\"#011627\",\"sideBarSectionHeader.foreground\":\"#5f7e97\",\"editorCursor.foreground\":\"#80a4c2\",\"editor.wordHighlightBackground\":\"#f6bbe533\",\"editor.wordHighlightStrongBackground\":\"#e2a2f433\",\"editor.lineHighlightBackground\":\"#0003\",\"editor.rangeHighlightBackground\":\"#7e57c25a\",\"editorIndentGuide.background\":\"#5e81ce52\",\"editorIndentGuide.activeBackground\":\"#7e97ac\",\"editorRuler.foreground\":\"#5e81ce52\",\"editorCodeLens.foreground\":\"#5e82ceb4\",\"editorBracketMatch.background\":\"#5f7e974d\",\"editorOverviewRuler.currentContentForeground\":\"#7e57c2\",\"editorOverviewRuler.incomingContentForeground\":\"#7e57c2\",\"editorOverviewRuler.commonContentForeground\":\"#7e57c2\",\"editorGutter.background\":\"#011627\",\"editorGutter.modifiedBackground\":\"#e2b93d\",\"editorGutter.addedBackground\":\"#9ccc65\",\"editorGutter.deletedBackground\":\"#ef5350\",\"editorSuggestWidget.background\":\"#2c3043\",\"editorSuggestWidget.border\":\"#2b2f40\",\"editorSuggestWidget.foreground\":\"#d6deeb\",\"editorSuggestWidget.highlightForeground\":\"#ffffff\",\"editorSuggestWidget.selectedBackground\":\"#5f7e97\",\"debugExceptionWidget.background\":\"#011627\",\"debugExceptionWidget.border\":\"#5f7e97\",\"editorMarkerNavigation.background\":\"#0b2942\",\"editorMarkerNavigationError.background\":\"#ef5350\",\"editorMarkerNavigationWarning.background\":\"#ffca28\",\"peekView.border\":\"#5f7e97\",\"peekViewEditor.background\":\"#011627\",\"peekViewEditor.matchHighlightBackground\":\"#7e57c25a\",\"peekViewResult.background\":\"#011627\",\"peekViewResult.fileForeground\":\"#5f7e97\",\"peekViewResult.lineForeground\":\"#5f7e97\",\"peekViewResult.matchHighlightBackground\":\"#ffffffcc\",\"peekViewResult.selectionBackground\":\"#2e3250\",\"peekViewResult.selectionForeground\":\"#5f7e97\",\"peekViewTitle.background\":\"#011627\",\"peekViewTitleDescription.foreground\":\"#697098\",\"peekViewTitleLabel.foreground\":\"#5f7e97\",\"merge.currentHeaderBackground\":\"#5f7e97\",\"merge.incomingHeaderBackground\":\"#7e57c25a\",\"statusBar.background\":\"#011627\",\"statusBar.foreground\":\"#5f7e97\",\"statusBar.border\":\"#262a39\",\"statusBar.debuggingBackground\":\"#202431\",\"statusBar.debuggingBorder\":\"#1f2330\",\"statusBar.noFolderBackground\":\"#011627\",\"statusBar.noFolderBorder\":\"#25293a\",\"statusBarItem.activeBackground\":\"#202431\",\"statusBarItem.hoverBackground\":\"#202431\",\"statusBarItem.prominentBackground\":\"#202431\",\"statusBarItem.prominentHoverBackground\":\"#202431\",\"notifications.background\":\"#01111d\",\"notifications.border\":\"#262a39\",\"notificationCenter.border\":\"#262a39\",\"notificationToast.border\":\"#262a39\",\"notifications.foreground\":\"#ffffffcc\",\"notificationLink.foreground\":\"#80cbc4\",\"extensionButton.prominentForeground\":\"#ffffffcc\",\"extensionButton.prominentBackground\":\"#7e57c2cc\",\"extensionButton.prominentHoverBackground\":\"#7e57c2\",\"terminal.selectionBackground\":\"#1b90dd4d\",\"terminalCursor.background\":\"#234d70\",\"debugToolBar.background\":\"#011627\",\"welcomePage.buttonBackground\":\"#011627\",\"welcomePage.buttonHoverBackground\":\"#011627\",\"walkThrough.embeddedEditorBackground\":\"#011627\",\"gitDecoration.modifiedResourceForeground\":\"#a2bffc\",\"gitDecoration.deletedResourceForeground\":\"#ef535090\",\"gitDecoration.untrackedResourceForeground\":\"#c5e478ff\",\"gitDecoration.ignoredResourceForeground\":\"#395a75\",\"gitDecoration.conflictingResourceForeground\":\"#ffeb95cc\",\"source.elm\":\"#5f7e97\",\"string.quoted.single.js\":\"#ffffff\",\"meta.objectliteral.js\":\"#82aaff\"},\"fg\":\"#d6deeb\",\"bg\":\"#23262f\",\"semanticHighlighting\":false,\"settings\":[{\"name\":\"Changed\",\"scope\":[\"markup.changed\",\"meta.diff.header.git\",\"meta.diff.header.from-file\",\"meta.diff.header.to-file\"],\"settings\":{\"foreground\":\"#a2bffc\"}},{\"name\":\"Deleted\",\"scope\":[\"markup.deleted.diff\"],\"settings\":{\"foreground\":\"#f27775fe\"}},{\"name\":\"Inserted\",\"scope\":[\"markup.inserted.diff\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Global settings\",\"settings\":{\"background\":\"#011627\",\"foreground\":\"#d6deeb\"}},{\"name\":\"Comment\",\"scope\":[\"comment\"],\"settings\":{\"foreground\":\"#919f9f\",\"fontStyle\":\"\"}},{\"name\":\"String\",\"scope\":[\"string\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"String Quoted\",\"scope\":[\"string.quoted\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"Support Constant Math\",\"scope\":[\"support.constant.math\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Number\",\"scope\":[\"constant.numeric\",\"constant.character.numeric\"],\"settings\":{\"foreground\":\"#f78c6c\",\"fontStyle\":\"\"}},{\"name\":\"Built-in constant\",\"scope\":[\"constant.language\",\"punctuation.definition.constant\",\"variable.other.constant\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"User-defined constant\",\"scope\":[\"constant.character\",\"constant.other\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Constant Character Escape\",\"scope\":[\"constant.character.escape\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"RegExp String\",\"scope\":[\"string.regexp\",\"string.regexp keyword.other\"],\"settings\":{\"foreground\":\"#5ca7e4\"}},{\"name\":\"Comma in functions\",\"scope\":[\"meta.function punctuation.separator.comma\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"Variable\",\"scope\":[\"variable\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Keyword\",\"scope\":[\"punctuation.accessor\",\"keyword\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Storage\",\"scope\":[\"storage\",\"meta.var.expr\",\"meta.class meta.method.declaration meta.var.expr storage.type.js\",\"storage.type.property.js\",\"storage.type.property.ts\",\"storage.type.property.tsx\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type.function.arrow.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Class name\",\"scope\":[\"entity.name.class\",\"meta.class entity.name.type.class\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Inherited class\",\"scope\":[\"entity.other.inherited-class\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Function name\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Meta Tag\",\"scope\":[\"punctuation.definition.tag\",\"meta.tag\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"HTML Tag names\",\"scope\":[\"entity.name.tag\",\"meta.tag.other.html\",\"meta.tag.other.js\",\"meta.tag.other.tsx\",\"entity.name.tag.tsx\",\"entity.name.tag.js\",\"entity.name.tag\",\"meta.tag.js\",\"meta.tag.tsx\",\"meta.tag.html\"],\"settings\":{\"foreground\":\"#caece6\",\"fontStyle\":\"\"}},{\"name\":\"Tag attribute\",\"scope\":[\"entity.other.attribute-name\"],\"settings\":{\"fontStyle\":\"\",\"foreground\":\"#c5e478\"}},{\"name\":\"Entity Name Tag Custom\",\"scope\":[\"entity.name.tag.custom\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Library (function & constant)\",\"scope\":[\"support.function\",\"support.constant\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Support Constant Property Value meta\",\"scope\":[\"support.constant.meta.property-value\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Library class/type\",\"scope\":[\"support.type\",\"support.class\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Support Variable DOM\",\"scope\":[\"support.variable.dom\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Invalid\",\"scope\":[\"invalid\"],\"settings\":{\"background\":\"#ff2c83\",\"foreground\":\"#ffffff\"}},{\"name\":\"Invalid deprecated\",\"scope\":[\"invalid.deprecated\"],\"settings\":{\"foreground\":\"#ffffff\",\"background\":\"#d3423e\"}},{\"name\":\"Keyword Operator\",\"scope\":[\"keyword.operator\"],\"settings\":{\"foreground\":\"#7fdbca\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Relational\",\"scope\":[\"keyword.operator.relational\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Assignment\",\"scope\":[\"keyword.operator.assignment\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Arithmetic\",\"scope\":[\"keyword.operator.arithmetic\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Bitwise\",\"scope\":[\"keyword.operator.bitwise\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Increment\",\"scope\":[\"keyword.operator.increment\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Ternary\",\"scope\":[\"keyword.operator.ternary\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Double-Slashed Comment\",\"scope\":[\"comment.line.double-slash\"],\"settings\":{\"foreground\":\"#919f9f\"}},{\"name\":\"Object\",\"scope\":[\"object\"],\"settings\":{\"foreground\":\"#cdebf7\"}},{\"name\":\"Null\",\"scope\":[\"constant.language.null\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Meta Brace\",\"scope\":[\"meta.brace\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Meta Delimiter Period\",\"scope\":[\"meta.delimiter.period\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Punctuation Definition String\",\"scope\":[\"punctuation.definition.string\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Punctuation Definition String Markdown\",\"scope\":[\"punctuation.definition.string.begin.markdown\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Boolean\",\"scope\":[\"constant.language.boolean\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Object Comma\",\"scope\":[\"object.comma\"],\"settings\":{\"foreground\":\"#ffffff\"}},{\"name\":\"Variable Parameter Function\",\"scope\":[\"variable.parameter.function\"],\"settings\":{\"foreground\":\"#7fdbca\",\"fontStyle\":\"\"}},{\"name\":\"Support Type Property Name & entity name tags\",\"scope\":[\"support.type.vendor.property-name\",\"support.constant.vendor.property-value\",\"support.type.property-name\",\"meta.property-list entity.name.tag\"],\"settings\":{\"foreground\":\"#80cbc4\",\"fontStyle\":\"\"}},{\"name\":\"Entity Name tag reference in stylesheets\",\"scope\":[\"meta.property-list entity.name.tag.reference\"],\"settings\":{\"foreground\":\"#57eaf1\"}},{\"name\":\"Constant Other Color RGB Value Punctuation Definition Constant\",\"scope\":[\"constant.other.color.rgb-value punctuation.definition.constant\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Constant Other Color\",\"scope\":[\"constant.other.color\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Keyword Other Unit\",\"scope\":[\"keyword.other.unit\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Meta Selector\",\"scope\":[\"meta.selector\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Entity Other Attribute Name Id\",\"scope\":[\"entity.other.attribute-name.id\"],\"settings\":{\"foreground\":\"#fad430\"}},{\"name\":\"Meta Property Name\",\"scope\":[\"meta.property-name\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Doctypes\",\"scope\":[\"entity.name.tag.doctype\",\"meta.tag.sgml.doctype\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Punctuation Definition Parameters\",\"scope\":[\"punctuation.definition.parameters\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Keyword Control Operator\",\"scope\":[\"keyword.control.operator\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Keyword Operator Logical\",\"scope\":[\"keyword.operator.logical\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Variable Instances\",\"scope\":[\"variable.instance\",\"variable.other.instance\",\"variable.readwrite.instance\",\"variable.other.readwrite.instance\",\"variable.other.property\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Variable Property Other object property\",\"scope\":[\"variable.other.object.property\"],\"settings\":{\"foreground\":\"#faf39f\",\"fontStyle\":\"\"}},{\"name\":\"Variable Property Other object\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Entity Name Function\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#82aaff\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Comparison, returns, imports, and Keyword Operator Ruby\",\"scope\":[\"keyword.control.conditional.js\",\"keyword.operator.comparison\",\"keyword.control.flow.js\",\"keyword.control.flow.ts\",\"keyword.control.flow.tsx\",\"keyword.control.ruby\",\"keyword.control.def.ruby\",\"keyword.control.loop.js\",\"keyword.control.loop.ts\",\"keyword.control.import.js\",\"keyword.control.import.ts\",\"keyword.control.import.tsx\",\"keyword.control.from.js\",\"keyword.control.from.ts\",\"keyword.control.from.tsx\",\"keyword.control.conditional.js\",\"keyword.control.conditional.ts\",\"keyword.control.switch.js\",\"keyword.control.switch.ts\",\"keyword.operator.instanceof.js\",\"keyword.operator.expression.instanceof.ts\",\"keyword.operator.expression.instanceof.tsx\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords\",\"scope\":[\"support.constant\",\"keyword.other.special-method\",\"keyword.other.new\",\"keyword.other.debugger\",\"keyword.control\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Support Function\",\"scope\":[\"support.function\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Invalid Broken\",\"scope\":[\"invalid.broken\"],\"settings\":{\"foreground\":\"#989da0\",\"background\":\"#F78C6C\"}},{\"name\":\"Invalid Unimplemented\",\"scope\":[\"invalid.unimplemented\"],\"settings\":{\"background\":\"#8BD649\",\"foreground\":\"#ffffff\"}},{\"name\":\"Invalid Illegal\",\"scope\":[\"invalid.illegal\"],\"settings\":{\"foreground\":\"#ffffff\",\"background\":\"#ec5f67\"}},{\"name\":\"Language Variable\",\"scope\":[\"variable.language\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Support Variable Property\",\"scope\":[\"support.variable.property\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Variable Function\",\"scope\":[\"variable.function\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Variable Interpolation\",\"scope\":[\"variable.interpolation\"],\"settings\":{\"foreground\":\"#ef787f\"}},{\"name\":\"Meta Function Call\",\"scope\":[\"meta.function-call\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Punctuation Section Embedded\",\"scope\":[\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#e2817f\"}},{\"name\":\"Punctuation Tweaks\",\"scope\":[\"punctuation.terminator.expression\",\"punctuation.definition.arguments\",\"punctuation.definition.array\",\"punctuation.section.array\",\"meta.array\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"More Punctuation Tweaks\",\"scope\":[\"punctuation.definition.list.begin\",\"punctuation.definition.list.end\",\"punctuation.separator.arguments\",\"punctuation.definition.list\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Template Strings\",\"scope\":[\"string.template meta.template.expression\"],\"settings\":{\"foreground\":\"#e2817f\"}},{\"name\":\"Backticks(``) in Template Strings\",\"scope\":[\"string.template punctuation.definition.string\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Italics\",\"scope\":[\"italic\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"italic\"}},{\"name\":\"Bold\",\"scope\":[\"bold\"],\"settings\":{\"foreground\":\"#c5e478\",\"fontStyle\":\"bold\"}},{\"name\":\"Quote\",\"scope\":[\"quote\"],\"settings\":{\"foreground\":\"#969bb7\",\"fontStyle\":\"\"}},{\"name\":\"Raw Code\",\"scope\":[\"raw\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"CoffeeScript Variable Assignment\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#31e1eb\"}},{\"name\":\"CoffeeScript Parameter Function\",\"scope\":[\"variable.parameter.function.coffee\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"CoffeeScript Assignments\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"C# Readwrite Variables\",\"scope\":[\"variable.other.readwrite.cs\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C# Classes & Storage types\",\"scope\":[\"entity.name.type.class.cs\",\"storage.type.cs\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"C# Namespaces\",\"scope\":[\"entity.name.type.namespace.cs\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"C# Unquoted String Zone\",\"scope\":[\"string.unquoted.preprocessor.message.cs\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C# Region\",\"scope\":[\"punctuation.separator.hash.cs\",\"keyword.preprocessor.region.cs\",\"keyword.preprocessor.endregion.cs\"],\"settings\":{\"foreground\":\"#ffcb8b\",\"fontStyle\":\"bold\"}},{\"name\":\"C# Other Variables\",\"scope\":[\"variable.other.object.cs\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"C# Enum\",\"scope\":[\"entity.name.type.enum.cs\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Dart String\",\"scope\":[\"string.interpolated.single.dart\",\"string.interpolated.double.dart\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Dart Class\",\"scope\":[\"support.class.dart\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Tag names in Stylesheets\",\"scope\":[\"entity.name.tag.css\",\"entity.name.tag.less\",\"entity.name.tag.custom.css\",\"support.constant.property-value.css\"],\"settings\":{\"foreground\":\"#ff6d6d\",\"fontStyle\":\"\"}},{\"name\":\"Wildcard(*) selector in Stylesheets\",\"scope\":[\"entity.name.tag.wildcard.css\",\"entity.name.tag.wildcard.less\",\"entity.name.tag.wildcard.scss\",\"entity.name.tag.wildcard.sass\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"CSS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Attribute Name for CSS\",\"scope\":[\"meta.attribute-selector.css entity.other.attribute-name.attribute\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Elixir Classes\",\"scope\":[\"source.elixir support.type.elixir\",\"source.elixir meta.module.elixir entity.name.class.elixir\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Elixir Functions\",\"scope\":[\"source.elixir entity.name.function\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir Constants\",\"scope\":[\"source.elixir constant.other.symbol.elixir\",\"source.elixir constant.other.keywords.elixir\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Elixir String Punctuations\",\"scope\":[\"source.elixir punctuation.definition.string\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir\",\"scope\":[\"source.elixir variable.other.readwrite.module.elixir\",\"source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir Binary Punctuations\",\"scope\":[\"source.elixir .punctuation.binary.elixir\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Closure Constant Keyword\",\"scope\":[\"constant.keyword.clojure\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Go Function Calls\",\"scope\":[\"source.go meta.function-call.go\"],\"settings\":{\"foreground\":\"#dddddd\"}},{\"name\":\"Go Keywords\",\"scope\":[\"source.go keyword.package.go\",\"source.go keyword.import.go\",\"source.go keyword.function.go\",\"source.go keyword.type.go\",\"source.go keyword.struct.go\",\"source.go keyword.interface.go\",\"source.go keyword.const.go\",\"source.go keyword.var.go\",\"source.go keyword.map.go\",\"source.go keyword.channel.go\",\"source.go keyword.control.go\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Go Constants e.g. nil, string format (%s, %d, etc.)\",\"scope\":[\"source.go constant.language.go\",\"source.go constant.other.placeholder.go\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"C++ Functions\",\"scope\":[\"entity.name.function.preprocessor.cpp\",\"entity.scope.name.cpp\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"C++ Meta Namespace\",\"scope\":[\"meta.namespace-block.cpp\"],\"settings\":{\"foreground\":\"#e0dec6\"}},{\"name\":\"C++ Language Primitive Storage\",\"scope\":[\"storage.type.language.primitive.cpp\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"C++ Preprocessor Macro\",\"scope\":[\"meta.preprocessor.macro.cpp\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C++ Variable Parameter\",\"scope\":[\"variable.parameter\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Powershell Variables\",\"scope\":[\"variable.other.readwrite.powershell\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Powershell Function\",\"scope\":[\"support.function.powershell\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"ID Attribute Name in HTML\",\"scope\":[\"entity.other.attribute-name.id.html\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"HTML Punctuation Definition Tag\",\"scope\":[\"punctuation.definition.tag.html\"],\"settings\":{\"foreground\":\"#6ae9f0\"}},{\"name\":\"HTML Doctype\",\"scope\":[\"meta.tag.sgml.doctype.html\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Classes\",\"scope\":[\"meta.class entity.name.type.class.js\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"JavaScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.js\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"JavaScript Terminator\",\"scope\":[\"terminator.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Meta Punctuation Definition\",\"scope\":[\"meta.js punctuation.definition.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Entity Names in Code Documentations\",\"scope\":[\"entity.name.type.instance.jsdoc\",\"entity.name.type.instance.phpdoc\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"Other Variables in Code Documentations\",\"scope\":[\"variable.other.jsdoc\",\"variable.other.phpdoc\"],\"settings\":{\"foreground\":\"#78ccf0\"}},{\"name\":\"JavaScript module imports and exports\",\"scope\":[\"variable.other.meta.import.js\",\"meta.import.js variable.other\",\"variable.other.meta.export.js\",\"meta.export.js variable.other\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Variable Parameter Function\",\"scope\":[\"variable.parameter.function.js\"],\"settings\":{\"foreground\":\"#8b96ea\"}},{\"name\":\"JavaScript[React] Variable Other Object\",\"scope\":[\"variable.other.object.js\",\"variable.other.object.jsx\",\"variable.object.property.js\",\"variable.object.property.jsx\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Variables\",\"scope\":[\"variable.js\",\"variable.other.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Entity Name Type\",\"scope\":[\"entity.name.type.js\",\"entity.name.type.module.js\"],\"settings\":{\"foreground\":\"#ffcb8b\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Support Classes\",\"scope\":[\"support.class.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JSON Property Names\",\"scope\":[\"support.type.property-name.json\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"JSON Support Constants\",\"scope\":[\"support.constant.json\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"JSON Property values (string)\",\"scope\":[\"meta.structure.dictionary.value.json string.quoted.double\"],\"settings\":{\"foreground\":\"#c789d6\"}},{\"name\":\"Strings in JSON values\",\"scope\":[\"string.quoted.double.json punctuation.definition.string.json\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Specific JSON Property values like null\",\"scope\":[\"meta.structure.dictionary.json meta.structure.dictionary.value constant.language\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"JavaScript Other Variable\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Ruby Variables\",\"scope\":[\"variable.other.ruby\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Ruby Class\",\"scope\":[\"entity.name.type.class.ruby\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"Ruby Hashkeys\",\"scope\":[\"constant.language.symbol.hashkey.ruby\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"LESS Tag names\",\"scope\":[\"entity.name.tag.less\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"LESS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Attribute Name for LESS\",\"scope\":[\"meta.attribute-selector.less entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Markdown Headings\",\"scope\":[\"markup.heading.markdown\",\"markup.heading.setext.1.markdown\",\"markup.heading.setext.2.markdown\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown Italics\",\"scope\":[\"markup.italic.markdown\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"italic\"}},{\"name\":\"Markdown Bold\",\"scope\":[\"markup.bold.markdown\"],\"settings\":{\"foreground\":\"#c5e478\",\"fontStyle\":\"bold\"}},{\"name\":\"Markdown Quote + others\",\"scope\":[\"markup.quote.markdown\"],\"settings\":{\"foreground\":\"#969bb7\",\"fontStyle\":\"\"}},{\"name\":\"Markdown Raw Code + others\",\"scope\":[\"markup.inline.raw.markdown\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Markdown Links\",\"scope\":[\"markup.underline.link.markdown\",\"markup.underline.link.image.markdown\"],\"settings\":{\"foreground\":\"#ff869a\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Link Title and Description\",\"scope\":[\"string.other.link.title.markdown\",\"string.other.link.description.markdown\"],\"settings\":{\"foreground\":\"#d6deeb\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Punctuation\",\"scope\":[\"punctuation.definition.string.markdown\",\"punctuation.definition.string.begin.markdown\",\"punctuation.definition.string.end.markdown\",\"meta.link.inline.markdown punctuation.definition.string\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown MetaData Punctuation\",\"scope\":[\"punctuation.definition.metadata.markdown\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Markdown List Punctuation\",\"scope\":[\"beginning.punctuation.definition.list.markdown\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown Inline Raw String\",\"scope\":[\"markup.inline.raw.string.markdown\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"PHP Variables\",\"scope\":[\"variable.other.php\"],\"settings\":{\"foreground\":\"#bec5d4\"}},{\"name\":\"Support Classes in PHP\",\"scope\":[\"support.class.php\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Punctuations in PHP function calls\",\"scope\":[\"meta.function-call.php punctuation\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"PHP Global Variables\",\"scope\":[\"variable.other.global.php\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Declaration Punctuation in PHP Global Variables\",\"scope\":[\"variable.other.global.php punctuation.definition.variable\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Language Constants in Python\",\"scope\":[\"constant.language.python\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Python Function Parameter and Arguments\",\"scope\":[\"variable.parameter.function.python\",\"meta.function-call.arguments.python\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Python Function Call\",\"scope\":[\"meta.function-call.python\",\"meta.function-call.generic.python\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"Punctuations in Python\",\"scope\":[\"punctuation.python\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Decorator Functions in Python\",\"scope\":[\"entity.name.function.decorator.python\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Python Language Variable\",\"scope\":[\"source.python variable.language.special\"],\"settings\":{\"foreground\":\"#8eace3\"}},{\"name\":\"Python import control keyword\",\"scope\":[\"keyword.control\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"SCSS Variable\",\"scope\":[\"variable.scss\",\"variable.sass\",\"variable.parameter.url.scss\",\"variable.parameter.url.sass\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#bec5d4\"}},{\"name\":\"Attribute Name for SASS\",\"scope\":[\"meta.attribute-selector.scss entity.other.attribute-name.attribute\",\"meta.attribute-selector.sass entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Tag names in SASS\",\"scope\":[\"entity.name.tag.scss\",\"entity.name.tag.sass\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"SASS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.scss\",\"keyword.other.unit.sass\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"TypeScript[React] Variables and Object Properties\",\"scope\":[\"variable.other.readwrite.alias.ts\",\"variable.other.readwrite.alias.tsx\",\"variable.other.readwrite.ts\",\"variable.other.readwrite.tsx\",\"variable.other.object.ts\",\"variable.other.object.tsx\",\"variable.object.property.ts\",\"variable.object.property.tsx\",\"variable.other.ts\",\"variable.other.tsx\",\"variable.tsx\",\"variable.ts\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript[React] Entity Name Types\",\"scope\":[\"entity.name.type.ts\",\"entity.name.type.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript[React] Node Classes\",\"scope\":[\"support.class.node.ts\",\"support.class.node.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"TypeScript[React] Entity Name Types as Parameters\",\"scope\":[\"meta.type.parameters.ts entity.name.type\",\"meta.type.parameters.tsx entity.name.type\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"TypeScript[React] Import/Export Punctuations\",\"scope\":[\"meta.import.ts punctuation.definition.block\",\"meta.import.tsx punctuation.definition.block\",\"meta.export.ts punctuation.definition.block\",\"meta.export.tsx punctuation.definition.block\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.decorator punctuation.decorator.ts\",\"meta.decorator punctuation.decorator.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.tag.js meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"YAML Entity Name Tags\",\"scope\":[\"entity.name.tag.yaml\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"JavaScript Variable Other ReadWrite\",\"scope\":[\"variable.other.readwrite.js\",\"variable.parameter\"],\"settings\":{\"foreground\":\"#d7dbe0\"}},{\"name\":\"Support Class Component\",\"scope\":[\"support.class.component.js\",\"support.class.component.tsx\"],\"settings\":{\"foreground\":\"#f78c6c\",\"fontStyle\":\"\"}},{\"name\":\"Text nested in React tags\",\"scope\":[\"meta.jsx.children\",\"meta.jsx.children.js\",\"meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript Classes\",\"scope\":[\"meta.class entity.name.type.class.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript Entity Name Type\",\"scope\":[\"entity.name.type.tsx\",\"entity.name.type.module.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript Class Variable Keyword\",\"scope\":[\"meta.class.ts meta.var.expr.ts storage.type.ts\",\"meta.class.tsx meta.var.expr.tsx storage.type.tsx\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"TypeScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.ts\",\"meta.method.declaration storage.type.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"normalize font style of certain components\",\"scope\":[\"meta.property-list.css meta.property-value.css variable.other.less\",\"meta.property-list.scss variable.scss\",\"meta.property-list.sass variable.sass\",\"meta.brace\",\"keyword.operator.operator\",\"keyword.operator.or.regexp\",\"keyword.operator.expression.in\",\"keyword.operator.relational\",\"keyword.operator.assignment\",\"keyword.operator.comparison\",\"keyword.operator.type\",\"keyword.operator\",\"keyword\",\"punctuation.definition.string\",\"punctuation\",\"variable.other.readwrite.js\",\"storage.type\",\"source.css\",\"string.quoted\"],\"settings\":{\"fontStyle\":\"\"}}],\"styleOverrides\":{\"frames\":{\"editorBackground\":\"var(--sl-color-gray-6)\",\"terminalBackground\":\"var(--sl-color-gray-6)\",\"editorActiveTabBackground\":\"var(--sl-color-gray-6)\",\"terminalTitlebarDotsForeground\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"terminalTitlebarDotsOpacity\":\"0.75\",\"inlineButtonForeground\":\"var(--sl-color-text)\",\"frameBoxShadowCssValue\":\"none\"},\"textMarkers\":{\"markBackground\":\"#ffffff17\",\"markBorderColor\":\"#ffffff40\"}}},{\"name\":\"Night Owl Light\",\"type\":\"light\",\"colors\":{\"focusBorder\":\"#93a1a1\",\"foreground\":\"#403f53\",\"disabledForeground\":\"#61616180\",\"descriptionForeground\":\"#403f53\",\"errorForeground\":\"#403f53\",\"icon.foreground\":\"#424242\",\"contrastActiveBorder\":null,\"contrastBorder\":null,\"textBlockQuote.background\":\"#7f7f7f1a\",\"textBlockQuote.border\":\"#007acc80\",\"textCodeBlock.background\":\"#dcdcdc66\",\"textLink.activeForeground\":\"#006ab1\",\"textLink.foreground\":\"#006ab1\",\"textPreformat.foreground\":\"#a31515\",\"textSeparator.foreground\":\"#0000002e\",\"editor.background\":\"#f6f7f9\",\"editor.foreground\":\"#403f53\",\"editorLineNumber.foreground\":\"#90a7b2\",\"editorLineNumber.activeForeground\":\"#403f53\",\"editorActiveLineNumber.foreground\":\"#0b216f\",\"editor.selectionBackground\":\"#e0e0e0\",\"editor.inactiveSelectionBackground\":\"#e0e0e080\",\"editor.selectionHighlightBackground\":\"#339cec33\",\"editorError.foreground\":\"#e64d49\",\"editorWarning.foreground\":\"#daaa01\",\"editorInfo.foreground\":\"#1a85ff\",\"editorHint.foreground\":\"#6c6c6c\",\"problemsErrorIcon.foreground\":\"#e64d49\",\"problemsWarningIcon.foreground\":\"#daaa01\",\"problemsInfoIcon.foreground\":\"#1a85ff\",\"editor.findMatchBackground\":\"#93a1a16c\",\"editor.findMatchHighlightBackground\":\"#93a1a16c\",\"editor.findRangeHighlightBackground\":\"#7497a633\",\"editorLink.activeForeground\":\"#0000ff\",\"editorLightBulb.foreground\":\"#ddb100\",\"editorLightBulbAutoFix.foreground\":\"#007acc\",\"diffEditor.insertedTextBackground\":\"#9ccc2c40\",\"diffEditor.insertedTextBorder\":null,\"diffEditor.removedTextBackground\":\"#ff000033\",\"diffEditor.removedTextBorder\":null,\"diffEditor.insertedLineBackground\":\"#9bb95533\",\"diffEditor.removedLineBackground\":\"#ff000033\",\"editorStickyScroll.background\":\"#fbfbfb\",\"editorStickyScrollHover.background\":\"#f0f0f0\",\"editorInlayHint.background\":\"#2aa29899\",\"editorInlayHint.foreground\":\"#f0f0f0\",\"editorInlayHint.typeBackground\":\"#2aa29899\",\"editorInlayHint.typeForeground\":\"#f0f0f0\",\"editorInlayHint.parameterBackground\":\"#2aa29899\",\"editorInlayHint.parameterForeground\":\"#f0f0f0\",\"editorPane.background\":\"#fbfbfb\",\"editorGroup.emptyBackground\":null,\"editorGroup.focusedEmptyBorder\":null,\"editorGroupHeader.tabsBackground\":\"var(--sl-color-gray-6)\",\"editorGroupHeader.tabsBorder\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"editorGroupHeader.noTabsBackground\":\"#f0f0f0\",\"editorGroupHeader.border\":null,\"editorGroup.border\":\"#f0f0f0\",\"editorGroup.dropBackground\":\"#2677cb2d\",\"editorGroup.dropIntoPromptForeground\":\"#403f53\",\"editorGroup.dropIntoPromptBackground\":\"#f0f0f0\",\"editorGroup.dropIntoPromptBorder\":null,\"sideBySideEditor.horizontalBorder\":\"#f0f0f0\",\"sideBySideEditor.verticalBorder\":\"#f0f0f0\",\"scrollbar.shadow\":\"#cccccc\",\"scrollbarSlider.background\":\"#0000001a\",\"scrollbarSlider.hoverBackground\":\"#00000055\",\"scrollbarSlider.activeBackground\":\"#00000099\",\"panel.background\":\"#f0f0f0\",\"panel.border\":\"#d9d9d9\",\"panelTitle.activeBorder\":\"#424242\",\"panelTitle.activeForeground\":\"#424242\",\"panelTitle.inactiveForeground\":\"#424242bf\",\"panelSectionHeader.background\":\"#80808051\",\"terminal.background\":\"#f6f6f6\",\"widget.shadow\":\"#d9d9d9\",\"editorWidget.background\":\"#f0f0f0\",\"editorWidget.foreground\":\"#403f53\",\"editorWidget.border\":\"#d9d9d9\",\"quickInput.background\":\"#f0f0f0\",\"quickInput.foreground\":\"#403f53\",\"quickInputTitle.background\":\"#0000000f\",\"pickerGroup.foreground\":\"#403f53\",\"pickerGroup.border\":\"#d9d9d9\",\"editor.hoverHighlightBackground\":\"#339cec33\",\"editorHoverWidget.background\":\"#f0f0f0\",\"editorHoverWidget.foreground\":\"#403f53\",\"editorHoverWidget.border\":\"#d9d9d9\",\"editorHoverWidget.statusBarBackground\":\"#e4e4e4\",\"titleBar.activeBackground\":\"var(--sl-color-gray-6)\",\"titleBar.activeForeground\":\"var(--sl-color-text)\",\"titleBar.inactiveBackground\":\"#f0f0f099\",\"titleBar.inactiveForeground\":\"#33333399\",\"titleBar.border\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"toolbar.hoverBackground\":\"#b8b8b850\",\"toolbar.activeBackground\":\"#a6a6a650\",\"tab.activeBackground\":\"#f6f6f6\",\"tab.unfocusedActiveBackground\":\"#f6f6f6\",\"tab.inactiveBackground\":\"#f0f0f0\",\"tab.unfocusedInactiveBackground\":\"#f0f0f0\",\"tab.activeForeground\":\"var(--sl-color-text)\",\"tab.inactiveForeground\":\"#403f53\",\"tab.unfocusedActiveForeground\":\"#403f53b3\",\"tab.unfocusedInactiveForeground\":\"#403f5380\",\"tab.hoverBackground\":null,\"tab.unfocusedHoverBackground\":null,\"tab.hoverForeground\":null,\"tab.unfocusedHoverForeground\":null,\"tab.border\":\"#f0f0f0\",\"tab.lastPinnedBorder\":\"#a9a9a9\",\"tab.activeBorder\":\"transparent\",\"tab.unfocusedActiveBorder\":null,\"tab.activeBorderTop\":\"var(--sl-color-accent)\",\"tab.unfocusedActiveBorderTop\":null,\"tab.hoverBorder\":null,\"tab.unfocusedHoverBorder\":null,\"tab.activeModifiedBorder\":\"#2aa298\",\"tab.inactiveModifiedBorder\":\"#93a1a1\",\"tab.unfocusedActiveModifiedBorder\":\"#93a1a1\",\"tab.unfocusedInactiveModifiedBorder\":\"#93a1a1\",\"badge.background\":\"#2aa298\",\"badge.foreground\":\"#f0f0f0\",\"button.background\":\"#2aa298\",\"button.foreground\":\"#f0f0f0\",\"button.border\":null,\"button.separator\":\"#f0f0f066\",\"button.hoverBackground\":\"#22827a\",\"button.secondaryBackground\":\"#5f6a79\",\"button.secondaryForeground\":\"#ffffff\",\"button.secondaryHoverBackground\":\"#4c5561\",\"dropdown.background\":\"#f0f0f0\",\"dropdown.foreground\":\"#403f53\",\"dropdown.border\":\"#d9d9d9\",\"list.activeSelectionBackground\":\"#d3e8f8\",\"list.activeSelectionForeground\":\"#403f53\",\"tree.indentGuidesStroke\":\"#a9a9a9\",\"input.background\":\"#f0f0f0\",\"input.foreground\":\"#403f53\",\"input.placeholderForeground\":\"#93a1a1\",\"inputOption.activeBorder\":\"#2aa298\",\"inputOption.hoverBackground\":\"#b8b8b850\",\"inputOption.activeBackground\":\"#93a1a133\",\"inputOption.activeForeground\":\"#000000\",\"inputValidation.infoBackground\":\"#f0f0f0\",\"inputValidation.infoBorder\":\"#d0d0d0\",\"inputValidation.warningBackground\":\"#daaa01\",\"inputValidation.warningBorder\":\"#e0af02\",\"inputValidation.errorBackground\":\"#f76e6e\",\"inputValidation.errorBorder\":\"#de3d3b\",\"keybindingLabel.background\":\"#dddddd66\",\"keybindingLabel.foreground\":\"#555555\",\"keybindingLabel.border\":\"#cccccc66\",\"keybindingLabel.bottomBorder\":\"#bbbbbb66\",\"menu.foreground\":\"#403f53\",\"menu.background\":\"#f0f0f0\",\"menu.selectionForeground\":\"#403f53\",\"menu.selectionBackground\":\"#d3e8f8\",\"menu.separatorBackground\":\"#d4d4d4\",\"editor.snippetTabstopHighlightBackground\":\"#0a326433\",\"editor.snippetFinalTabstopHighlightBorder\":\"#0a326480\",\"terminal.ansiBlack\":\"#403f53\",\"terminal.ansiRed\":\"#de3d3b\",\"terminal.ansiGreen\":\"#08916a\",\"terminal.ansiYellow\":\"#e0af02\",\"terminal.ansiBlue\":\"#288ed7\",\"terminal.ansiMagenta\":\"#d6438a\",\"terminal.ansiCyan\":\"#2aa298\",\"terminal.ansiWhite\":\"#f0f0f0\",\"terminal.ansiBrightBlack\":\"#403f53\",\"terminal.ansiBrightRed\":\"#de3d3b\",\"terminal.ansiBrightGreen\":\"#08916a\",\"terminal.ansiBrightYellow\":\"#daaa01\",\"terminal.ansiBrightBlue\":\"#288ed7\",\"terminal.ansiBrightMagenta\":\"#d6438a\",\"terminal.ansiBrightCyan\":\"#2aa298\",\"terminal.ansiBrightWhite\":\"#f0f0f0\",\"selection.background\":\"#7a8181ad\",\"notifications.background\":\"#f0f0f0\",\"notifications.foreground\":\"#403f53\",\"notificationLink.foreground\":\"#994cc3\",\"notifications.border\":\"#cccccc\",\"notificationCenter.border\":\"#cccccc\",\"notificationToast.border\":\"#cccccc\",\"notificationCenterHeader.foreground\":\"#403f53\",\"notificationCenterHeader.background\":\"#f0f0f0\",\"input.border\":\"#d9d9d9\",\"progressBar.background\":\"#2aa298\",\"list.inactiveSelectionBackground\":\"#e0e7ea\",\"list.inactiveSelectionForeground\":\"#403f53\",\"list.focusBackground\":\"#d3e8f8\",\"list.hoverBackground\":\"#d3e8f8\",\"list.focusForeground\":\"#403f53\",\"list.hoverForeground\":\"#403f53\",\"list.highlightForeground\":\"#403f53\",\"list.errorForeground\":\"#e64d49\",\"list.warningForeground\":\"#daaa01\",\"activityBar.background\":\"#f0f0f0\",\"activityBar.foreground\":\"#403f53\",\"activityBar.dropBackground\":\"#d0d0d0\",\"activityBarBadge.background\":\"#403f53\",\"activityBarBadge.foreground\":\"#f0f0f0\",\"activityBar.border\":\"#f0f0f0\",\"sideBar.background\":\"#f0f0f0\",\"sideBar.foreground\":\"#403f53\",\"sideBarTitle.foreground\":\"#403f53\",\"sideBar.border\":\"#f0f0f0\",\"editorGroup.background\":\"#f6f6f6\",\"editorCursor.foreground\":\"#90a7b2\",\"editor.wordHighlightBackground\":\"#339cec33\",\"editor.wordHighlightStrongBackground\":\"#007dd659\",\"editor.lineHighlightBackground\":\"#f0f0f0\",\"editor.rangeHighlightBackground\":\"#7497a633\",\"editorWhitespace.foreground\":\"#d9d9d9\",\"editorIndentGuide.background\":\"#d9d9d9\",\"editorCodeLens.foreground\":\"#403f53\",\"editorBracketMatch.background\":\"#d3e8f8\",\"editorBracketMatch.border\":\"#2aa298\",\"editorError.border\":\"#fbfbfb\",\"editorWarning.border\":\"#daaa01\",\"editorGutter.addedBackground\":\"#49d0c5\",\"editorGutter.modifiedBackground\":\"#6fbef6\",\"editorGutter.deletedBackground\":\"#f76e6e\",\"editorRuler.foreground\":\"#d9d9d9\",\"editorOverviewRuler.errorForeground\":\"#e64d49\",\"editorOverviewRuler.warningForeground\":\"#daaa01\",\"editorSuggestWidget.background\":\"#f0f0f0\",\"editorSuggestWidget.foreground\":\"#403f53\",\"editorSuggestWidget.highlightForeground\":\"#403f53\",\"editorSuggestWidget.selectedBackground\":\"#d3e8f8\",\"editorSuggestWidget.border\":\"#d9d9d9\",\"debugExceptionWidget.background\":\"#f0f0f0\",\"debugExceptionWidget.border\":\"#d9d9d9\",\"editorMarkerNavigation.background\":\"#d0d0d0\",\"editorMarkerNavigationError.background\":\"#f76e6e\",\"editorMarkerNavigationWarning.background\":\"#daaa01\",\"debugToolBar.background\":\"#f0f0f0\",\"extensionButton.prominentBackground\":\"#2aa298\",\"extensionButton.prominentForeground\":\"#f0f0f0\",\"statusBar.background\":\"#f0f0f0\",\"statusBar.border\":\"#f0f0f0\",\"statusBar.debuggingBackground\":\"#f0f0f0\",\"statusBar.debuggingForeground\":\"#403f53\",\"statusBar.foreground\":\"#403f53\",\"statusBar.noFolderBackground\":\"#f0f0f0\",\"statusBar.noFolderForeground\":\"#403f53\",\"peekView.border\":\"#d9d9d9\",\"peekViewEditor.background\":\"#f6f6f6\",\"peekViewEditorGutter.background\":\"#f6f6f6\",\"peekViewEditor.matchHighlightBackground\":\"#49d0c5\",\"peekViewResult.background\":\"#f0f0f0\",\"peekViewResult.fileForeground\":\"#403f53\",\"peekViewResult.lineForeground\":\"#403f53\",\"peekViewResult.matchHighlightBackground\":\"#49d0c5\",\"peekViewResult.selectionBackground\":\"#e0e7ea\",\"peekViewResult.selectionForeground\":\"#403f53\",\"peekViewTitle.background\":\"#f0f0f0\",\"peekViewTitleLabel.foreground\":\"#403f53\",\"peekViewTitleDescription.foreground\":\"#403f53\",\"terminal.foreground\":\"#403f53\"},\"fg\":\"#403f53\",\"bg\":\"#f6f7f9\",\"semanticHighlighting\":false,\"settings\":[{\"name\":\"Changed\",\"scope\":[\"markup.changed\",\"meta.diff.header.git\",\"meta.diff.header.from-file\",\"meta.diff.header.to-file\"],\"settings\":{\"foreground\":\"#556484\"}},{\"name\":\"Deleted\",\"scope\":[\"markup.deleted.diff\"],\"settings\":{\"foreground\":\"#ae3c3afd\"}},{\"name\":\"Inserted\",\"scope\":[\"markup.inserted.diff\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Global settings\",\"settings\":{\"background\":\"#011627\",\"foreground\":\"#403f53\"}},{\"name\":\"Comment\",\"scope\":[\"comment\"],\"settings\":{\"foreground\":\"#5f636f\"}},{\"name\":\"String\",\"scope\":[\"string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"String Quoted\",\"scope\":[\"string.quoted\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Support Constant Math\",\"scope\":[\"support.constant.math\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Number\",\"scope\":[\"constant.numeric\",\"constant.character.numeric\"],\"settings\":{\"foreground\":\"#aa0982\",\"fontStyle\":\"\"}},{\"name\":\"Built-in constant\",\"scope\":[\"constant.language\",\"punctuation.definition.constant\",\"variable.other.constant\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"User-defined constant\",\"scope\":[\"constant.character\",\"constant.other\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Constant Character Escape\",\"scope\":[\"constant.character.escape\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"RegExp String\",\"scope\":[\"string.regexp\",\"string.regexp keyword.other\"],\"settings\":{\"foreground\":\"#3a688f\"}},{\"name\":\"Comma in functions\",\"scope\":[\"meta.function punctuation.separator.comma\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"Variable\",\"scope\":[\"variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Keyword\",\"scope\":[\"punctuation.accessor\",\"keyword\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage\",\"scope\":[\"storage\",\"meta.var.expr\",\"meta.class meta.method.declaration meta.var.expr storage.type.js\",\"storage.type.property.js\",\"storage.type.property.ts\",\"storage.type.property.tsx\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type.function.arrow.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Class name\",\"scope\":[\"entity.name.class\",\"meta.class entity.name.type.class\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Inherited class\",\"scope\":[\"entity.other.inherited-class\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Function name\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Meta Tag\",\"scope\":[\"punctuation.definition.tag\",\"meta.tag\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"HTML Tag names\",\"scope\":[\"entity.name.tag\",\"meta.tag.other.html\",\"meta.tag.other.js\",\"meta.tag.other.tsx\",\"entity.name.tag.tsx\",\"entity.name.tag.js\",\"entity.name.tag\",\"meta.tag.js\",\"meta.tag.tsx\",\"meta.tag.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Tag attribute\",\"scope\":[\"entity.other.attribute-name\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Entity Name Tag Custom\",\"scope\":[\"entity.name.tag.custom\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Library (function & constant)\",\"scope\":[\"support.function\",\"support.constant\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Support Constant Property Value meta\",\"scope\":[\"support.constant.meta.property-value\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Library class/type\",\"scope\":[\"support.type\",\"support.class\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Support Variable DOM\",\"scope\":[\"support.variable.dom\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Invalid\",\"scope\":[\"invalid\"],\"settings\":{\"foreground\":\"#bb2060\"}},{\"name\":\"Invalid deprecated\",\"scope\":[\"invalid.deprecated\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Keyword Operator\",\"scope\":[\"keyword.operator\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Relational\",\"scope\":[\"keyword.operator.relational\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Assignment\",\"scope\":[\"keyword.operator.assignment\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Arithmetic\",\"scope\":[\"keyword.operator.arithmetic\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Bitwise\",\"scope\":[\"keyword.operator.bitwise\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Increment\",\"scope\":[\"keyword.operator.increment\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Ternary\",\"scope\":[\"keyword.operator.ternary\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Double-Slashed Comment\",\"scope\":[\"comment.line.double-slash\"],\"settings\":{\"foreground\":\"#5d6376\"}},{\"name\":\"Object\",\"scope\":[\"object\"],\"settings\":{\"foreground\":\"#58656a\"}},{\"name\":\"Null\",\"scope\":[\"constant.language.null\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Meta Brace\",\"scope\":[\"meta.brace\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Meta Delimiter Period\",\"scope\":[\"meta.delimiter.period\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Punctuation Definition String\",\"scope\":[\"punctuation.definition.string\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Punctuation Definition String Markdown\",\"scope\":[\"punctuation.definition.string.begin.markdown\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Boolean\",\"scope\":[\"constant.language.boolean\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Object Comma\",\"scope\":[\"object.comma\"],\"settings\":{\"foreground\":\"#646464\"}},{\"name\":\"Variable Parameter Function\",\"scope\":[\"variable.parameter.function\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Support Type Property Name & entity name tags\",\"scope\":[\"support.type.vendor.property-name\",\"support.constant.vendor.property-value\",\"support.type.property-name\",\"meta.property-list entity.name.tag\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Entity Name tag reference in stylesheets\",\"scope\":[\"meta.property-list entity.name.tag.reference\"],\"settings\":{\"foreground\":\"#286d70\"}},{\"name\":\"Constant Other Color RGB Value Punctuation Definition Constant\",\"scope\":[\"constant.other.color.rgb-value punctuation.definition.constant\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Constant Other Color\",\"scope\":[\"constant.other.color\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Keyword Other Unit\",\"scope\":[\"keyword.other.unit\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Meta Selector\",\"scope\":[\"meta.selector\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Entity Other Attribute Name Id\",\"scope\":[\"entity.other.attribute-name.id\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Meta Property Name\",\"scope\":[\"meta.property-name\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Doctypes\",\"scope\":[\"entity.name.tag.doctype\",\"meta.tag.sgml.doctype\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Punctuation Definition Parameters\",\"scope\":[\"punctuation.definition.parameters\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Keyword Control Operator\",\"scope\":[\"keyword.control.operator\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Keyword Operator Logical\",\"scope\":[\"keyword.operator.logical\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"\"}},{\"name\":\"Variable Instances\",\"scope\":[\"variable.instance\",\"variable.other.instance\",\"variable.readwrite.instance\",\"variable.other.readwrite.instance\",\"variable.other.property\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Variable Property Other object property\",\"scope\":[\"variable.other.object.property\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Variable Property Other object\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Entity Name Function\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Keyword Operator Comparison, imports, returns and Keyword Operator Ruby\",\"scope\":[\"keyword.operator.comparison\",\"keyword.control.flow.js\",\"keyword.control.flow.ts\",\"keyword.control.flow.tsx\",\"keyword.control.ruby\",\"keyword.control.module.ruby\",\"keyword.control.class.ruby\",\"keyword.control.def.ruby\",\"keyword.control.loop.js\",\"keyword.control.loop.ts\",\"keyword.control.import.js\",\"keyword.control.import.ts\",\"keyword.control.import.tsx\",\"keyword.control.from.js\",\"keyword.control.from.ts\",\"keyword.control.from.tsx\",\"keyword.operator.instanceof.js\",\"keyword.operator.expression.instanceof.ts\",\"keyword.operator.expression.instanceof.tsx\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Control Conditional\",\"scope\":[\"keyword.control.conditional.js\",\"keyword.control.conditional.ts\",\"keyword.control.switch.js\",\"keyword.control.switch.ts\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"\"}},{\"name\":\"Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords\",\"scope\":[\"support.constant\",\"keyword.other.special-method\",\"keyword.other.new\",\"keyword.other.debugger\",\"keyword.control\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Support Function\",\"scope\":[\"support.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Invalid Broken\",\"scope\":[\"invalid.broken\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Invalid Unimplemented\",\"scope\":[\"invalid.unimplemented\"],\"settings\":{\"foreground\":\"#486e26\"}},{\"name\":\"Invalid Illegal\",\"scope\":[\"invalid.illegal\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Language Variable\",\"scope\":[\"variable.language\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Support Variable Property\",\"scope\":[\"support.variable.property\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Variable Function\",\"scope\":[\"variable.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variable Interpolation\",\"scope\":[\"variable.interpolation\"],\"settings\":{\"foreground\":\"#a64348\"}},{\"name\":\"Meta Function Call\",\"scope\":[\"meta.function-call\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Punctuation Section Embedded\",\"scope\":[\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Punctuation Tweaks\",\"scope\":[\"punctuation.terminator.expression\",\"punctuation.definition.arguments\",\"punctuation.definition.array\",\"punctuation.section.array\",\"meta.array\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"More Punctuation Tweaks\",\"scope\":[\"punctuation.definition.list.begin\",\"punctuation.definition.list.end\",\"punctuation.separator.arguments\",\"punctuation.definition.list\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Template Strings\",\"scope\":[\"string.template meta.template.expression\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Backticks(``) in Template Strings\",\"scope\":[\"string.template punctuation.definition.string\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Italics\",\"scope\":[\"italic\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"italic\"}},{\"name\":\"Bold\",\"scope\":[\"bold\"],\"settings\":{\"foreground\":\"#3b61b0\",\"fontStyle\":\"bold\"}},{\"name\":\"Quote\",\"scope\":[\"quote\"],\"settings\":{\"foreground\":\"#5c6285\"}},{\"name\":\"Raw Code\",\"scope\":[\"raw\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"CoffeeScript Variable Assignment\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#186e73\"}},{\"name\":\"CoffeeScript Parameter Function\",\"scope\":[\"variable.parameter.function.coffee\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"CoffeeScript Assignments\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"C# Readwrite Variables\",\"scope\":[\"variable.other.readwrite.cs\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"C# Classes & Storage types\",\"scope\":[\"entity.name.type.class.cs\",\"storage.type.cs\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"C# Namespaces\",\"scope\":[\"entity.name.type.namespace.cs\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Tag names in Stylesheets\",\"scope\":[\"entity.name.tag.css\",\"entity.name.tag.less\",\"entity.name.tag.custom.css\",\"support.constant.property-value.css\"],\"settings\":{\"foreground\":\"#984e4d\",\"fontStyle\":\"\"}},{\"name\":\"Wildcard(*) selector in Stylesheets\",\"scope\":[\"entity.name.tag.wildcard.css\",\"entity.name.tag.wildcard.less\",\"entity.name.tag.wildcard.scss\",\"entity.name.tag.wildcard.sass\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"CSS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Attribute Name for CSS\",\"scope\":[\"meta.attribute-selector.css entity.other.attribute-name.attribute\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Elixir Classes\",\"scope\":[\"source.elixir support.type.elixir\",\"source.elixir meta.module.elixir entity.name.class.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Functions\",\"scope\":[\"source.elixir entity.name.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Constants\",\"scope\":[\"source.elixir constant.other.symbol.elixir\",\"source.elixir constant.other.keywords.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir String Punctuations\",\"scope\":[\"source.elixir punctuation.definition.string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir\",\"scope\":[\"source.elixir variable.other.readwrite.module.elixir\",\"source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Binary Punctuations\",\"scope\":[\"source.elixir .punctuation.binary.elixir\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Closure Constant Keyword\",\"scope\":[\"constant.keyword.clojure\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Go Function Calls\",\"scope\":[\"source.go meta.function-call.go\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Go Keywords\",\"scope\":[\"source.go keyword.package.go\",\"source.go keyword.import.go\",\"source.go keyword.function.go\",\"source.go keyword.type.go\",\"source.go keyword.struct.go\",\"source.go keyword.interface.go\",\"source.go keyword.const.go\",\"source.go keyword.var.go\",\"source.go keyword.map.go\",\"source.go keyword.channel.go\",\"source.go keyword.control.go\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Go Constants e.g. nil, string format (%s, %d, etc.)\",\"scope\":[\"source.go constant.language.go\",\"source.go constant.other.placeholder.go\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"C++ Functions\",\"scope\":[\"entity.name.function.preprocessor.cpp\",\"entity.scope.name.cpp\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"C++ Meta Namespace\",\"scope\":[\"meta.namespace-block.cpp\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"C++ Language Primitive Storage\",\"scope\":[\"storage.type.language.primitive.cpp\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"C++ Preprocessor Macro\",\"scope\":[\"meta.preprocessor.macro.cpp\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"C++ Variable Parameter\",\"scope\":[\"variable.parameter\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Powershell Variables\",\"scope\":[\"variable.other.readwrite.powershell\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Powershell Function\",\"scope\":[\"support.function.powershell\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"ID Attribute Name in HTML\",\"scope\":[\"entity.other.attribute-name.id.html\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"HTML Punctuation Definition Tag\",\"scope\":[\"punctuation.definition.tag.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"HTML Doctype\",\"scope\":[\"meta.tag.sgml.doctype.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"JavaScript Classes\",\"scope\":[\"meta.class entity.name.type.class.js\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"JavaScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.js\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"JavaScript Terminator\",\"scope\":[\"terminator.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Meta Punctuation Definition\",\"scope\":[\"meta.js punctuation.definition.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Entity Names in Code Documentations\",\"scope\":[\"entity.name.type.instance.jsdoc\",\"entity.name.type.instance.phpdoc\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"Other Variables in Code Documentations\",\"scope\":[\"variable.other.jsdoc\",\"variable.other.phpdoc\"],\"settings\":{\"foreground\":\"#3e697c\"}},{\"name\":\"JavaScript module imports and exports\",\"scope\":[\"variable.other.meta.import.js\",\"meta.import.js variable.other\",\"variable.other.meta.export.js\",\"meta.export.js variable.other\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Variable Parameter Function\",\"scope\":[\"variable.parameter.function.js\"],\"settings\":{\"foreground\":\"#555ea2\"}},{\"name\":\"JavaScript[React] Variable Other Object\",\"scope\":[\"variable.other.object.js\",\"variable.other.object.jsx\",\"variable.object.property.js\",\"variable.object.property.jsx\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Variables\",\"scope\":[\"variable.js\",\"variable.other.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Entity Name Type\",\"scope\":[\"entity.name.type.js\",\"entity.name.type.module.js\"],\"settings\":{\"foreground\":\"#111111\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Support Classes\",\"scope\":[\"support.class.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JSON Property Names\",\"scope\":[\"support.type.property-name.json\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"JSON Support Constants\",\"scope\":[\"support.constant.json\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"JSON Property values (string)\",\"scope\":[\"meta.structure.dictionary.value.json string.quoted.double\"],\"settings\":{\"foreground\":\"#7c5686\"}},{\"name\":\"Strings in JSON values\",\"scope\":[\"string.quoted.double.json punctuation.definition.string.json\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Specific JSON Property values like null\",\"scope\":[\"meta.structure.dictionary.json meta.structure.dictionary.value constant.language\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"JavaScript Other Variable\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Ruby Variables\",\"scope\":[\"variable.other.ruby\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Ruby Class\",\"scope\":[\"entity.name.type.class.ruby\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Ruby Hashkeys\",\"scope\":[\"constant.language.symbol.hashkey.ruby\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Ruby Symbols\",\"scope\":[\"constant.language.symbol.ruby\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"LESS Tag names\",\"scope\":[\"entity.name.tag.less\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"LESS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Attribute Name for LESS\",\"scope\":[\"meta.attribute-selector.less entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Markdown Headings\",\"scope\":[\"markup.heading.markdown\",\"markup.heading.setext.1.markdown\",\"markup.heading.setext.2.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown Italics\",\"scope\":[\"markup.italic.markdown\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"italic\"}},{\"name\":\"Markdown Bold\",\"scope\":[\"markup.bold.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\",\"fontStyle\":\"bold\"}},{\"name\":\"Markdown Quote + others\",\"scope\":[\"markup.quote.markdown\"],\"settings\":{\"foreground\":\"#5c6285\"}},{\"name\":\"Markdown Raw Code + others\",\"scope\":[\"markup.inline.raw.markdown\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Markdown Links\",\"scope\":[\"markup.underline.link.markdown\",\"markup.underline.link.image.markdown\"],\"settings\":{\"foreground\":\"#954f5a\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Link Title and Description\",\"scope\":[\"string.other.link.title.markdown\",\"string.other.link.description.markdown\"],\"settings\":{\"foreground\":\"#403f53\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Punctuation\",\"scope\":[\"punctuation.definition.string.markdown\",\"punctuation.definition.string.begin.markdown\",\"punctuation.definition.string.end.markdown\",\"meta.link.inline.markdown punctuation.definition.string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown MetaData Punctuation\",\"scope\":[\"punctuation.definition.metadata.markdown\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Markdown List Punctuation\",\"scope\":[\"beginning.punctuation.definition.list.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown Inline Raw String\",\"scope\":[\"markup.inline.raw.string.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"PHP Variables\",\"scope\":[\"variable.other.php\",\"variable.other.property.php\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Support Classes in PHP\",\"scope\":[\"support.class.php\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Punctuations in PHP function calls\",\"scope\":[\"meta.function-call.php punctuation\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"PHP Global Variables\",\"scope\":[\"variable.other.global.php\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Declaration Punctuation in PHP Global Variables\",\"scope\":[\"variable.other.global.php punctuation.definition.variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Language Constants in Python\",\"scope\":[\"constant.language.python\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Python Function Parameter and Arguments\",\"scope\":[\"variable.parameter.function.python\",\"meta.function-call.arguments.python\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Python Function Call\",\"scope\":[\"meta.function-call.python\",\"meta.function-call.generic.python\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Punctuations in Python\",\"scope\":[\"punctuation.python\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Decorator Functions in Python\",\"scope\":[\"entity.name.function.decorator.python\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Python Language Variable\",\"scope\":[\"source.python variable.language.special\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Python import control keyword\",\"scope\":[\"keyword.control\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"SCSS Variable\",\"scope\":[\"variable.scss\",\"variable.sass\",\"variable.parameter.url.scss\",\"variable.parameter.url.sass\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Attribute Name for SASS\",\"scope\":[\"meta.attribute-selector.scss entity.other.attribute-name.attribute\",\"meta.attribute-selector.sass entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Tag names in SASS\",\"scope\":[\"entity.name.tag.scss\",\"entity.name.tag.sass\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"SASS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.scss\",\"keyword.other.unit.sass\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"TypeScript[React] Variables and Object Properties\",\"scope\":[\"variable.other.readwrite.alias.ts\",\"variable.other.readwrite.alias.tsx\",\"variable.other.readwrite.ts\",\"variable.other.readwrite.tsx\",\"variable.other.object.ts\",\"variable.other.object.tsx\",\"variable.object.property.ts\",\"variable.object.property.tsx\",\"variable.other.ts\",\"variable.other.tsx\",\"variable.tsx\",\"variable.ts\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript[React] Entity Name Types\",\"scope\":[\"entity.name.type.ts\",\"entity.name.type.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript[React] Node Classes\",\"scope\":[\"support.class.node.ts\",\"support.class.node.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"TypeScript[React] Entity Name Types as Parameters\",\"scope\":[\"meta.type.parameters.ts entity.name.type\",\"meta.type.parameters.tsx entity.name.type\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"TypeScript[React] Import/Export Punctuations\",\"scope\":[\"meta.import.ts punctuation.definition.block\",\"meta.import.tsx punctuation.definition.block\",\"meta.export.ts punctuation.definition.block\",\"meta.export.tsx punctuation.definition.block\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.decorator punctuation.decorator.ts\",\"meta.decorator punctuation.decorator.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.tag.js meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"YAML Entity Name Tags\",\"scope\":[\"entity.name.tag.yaml\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"JavaScript Variable Other ReadWrite\",\"scope\":[\"variable.other.readwrite.js\",\"variable.parameter\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Support Class Component\",\"scope\":[\"support.class.component.js\",\"support.class.component.tsx\"],\"settings\":{\"foreground\":\"#aa0982\",\"fontStyle\":\"\"}},{\"name\":\"Text nested in React tags\",\"scope\":[\"meta.jsx.children\",\"meta.jsx.children.js\",\"meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript Classes\",\"scope\":[\"meta.class entity.name.type.class.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript Entity Name Type\",\"scope\":[\"entity.name.type.tsx\",\"entity.name.type.module.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript Class Variable Keyword\",\"scope\":[\"meta.class.ts meta.var.expr.ts storage.type.ts\",\"meta.class.tsx meta.var.expr.tsx storage.type.tsx\"],\"settings\":{\"foreground\":\"#76578b\"}},{\"name\":\"TypeScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.ts\",\"meta.method.declaration storage.type.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"normalize font style of certain components\",\"scope\":[\"meta.property-list.css meta.property-value.css variable.other.less\",\"meta.property-list.scss variable.scss\",\"meta.property-list.sass variable.sass\",\"meta.brace\",\"keyword.operator.operator\",\"keyword.operator.or.regexp\",\"keyword.operator.expression.in\",\"keyword.operator.relational\",\"keyword.operator.assignment\",\"keyword.operator.comparison\",\"keyword.operator.type\",\"keyword.operator\",\"keyword\",\"punctuation.definition.string\",\"punctuation\",\"variable.other.readwrite.js\",\"storage.type\",\"source.css\",\"string.quoted\"],\"settings\":{\"fontStyle\":\"\"}}],\"styleOverrides\":{\"frames\":{\"editorBackground\":\"var(--sl-color-gray-7)\",\"terminalBackground\":\"var(--sl-color-gray-7)\",\"editorActiveTabBackground\":\"var(--sl-color-gray-7)\",\"terminalTitlebarDotsForeground\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"terminalTitlebarDotsOpacity\":\"0.75\",\"inlineButtonForeground\":\"var(--sl-color-text)\",\"frameBoxShadowCssValue\":\"none\"},\"textMarkers\":{\"markBackground\":\"#0000001a\",\"markBorderColor\":\"#00000055\"}}}],\"defaultLocale\":\"en\",\"cascadeLayer\":\"starlight.components\",\"styleOverrides\":{\"borderRadius\":\"0px\",\"borderWidth\":\"1px\",\"codePaddingBlock\":\"0.75rem\",\"codePaddingInline\":\"1rem\",\"codeFontFamily\":\"var(--__sl-font-mono)\",\"codeFontSize\":\"var(--sl-text-code)\",\"codeLineHeight\":\"var(--sl-line-height)\",\"uiFontFamily\":\"var(--__sl-font)\",\"textMarkers\":{\"lineDiffIndicatorMarginLeft\":\"0.25rem\",\"defaultChroma\":\"45\",\"backgroundOpacity\":\"60%\"}},\"plugins\":[{\"name\":\"Starlight Plugin\",\"hooks\":{}},{\"name\":\"astro-expressive-code\",\"hooks\":{}}]}]],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true,\"allowedDomains\":[],\"actionBodySizeLimit\":1048576},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"headingIdCompat\":false,\"preserveScriptOrder\":false,\"liveContentCollections\":false,\"csp\":false,\"staticImportMetaEnv\":false,\"chromeDevtoolsWorkspace\":false,\"failOnPrerenderConflict\":false,\"svgo\":false},\"legacy\":{\"collections\":false},\"prefetch\":{\"prefetchAll\":true},\"i18n\":{\"defaultLocale\":\"en\",\"locales\":[\"en\"],\"routing\":{\"prefixDefaultLocale\":false,\"redirectToDefaultLocale\":false,\"fallbackType\":\"redirect\"}}}","docs",["Map",11,12,27,28,47,48,66,67,89,90,108,109,127,128,149,150],"index",{"id":11,"data":13,"filePath":25,"digest":26,"deferredRender":16},{"title":14,"description":15,"editUrl":16,"head":17,"template":18,"hero":19,"sidebar":22,"pagefind":16,"draft":23},"CreateHer Fest","Let's build some sample applications!",true,[],"splash",{"tagline":20,"actions":21},"DIALED IN! Answer calls in WebXR.",[],{"hidden":23,"attrs":24},false,{},"src/content/docs/index.mdx","5742d2bb91f1973b","02_setup_application",{"id":27,"data":29,"body":36,"filePath":37,"digest":38,"rendered":39},{"title":30,"description":31,"editUrl":16,"head":32,"template":33,"sidebar":34,"pagefind":16,"draft":23},"Setup Application","Create an application.",[],"doc",{"hidden":23,"attrs":35},{},"> Note: Please make sure to redeem the coupon code to your Vonage account's \u003Ca href=\"https://dashboard.vonage.com/coupons\" target=\"_blank\">dashboard\u003C/a> before continuing. It is needed to purchase a phone number.\n\nIn the terminal below, you should see a set up script running asking for your `API key`. Complete the steps in the set up script. This will create an Application with Voice functionality, purchase a phone number, and create the needed Webhook endpoints.\n\n> Note: You can get your credentials in the \u003Ca href=\"https://dashboard.vonage.com/settings\" target=\"_blank\">Vonage dashboard Settings Page\u003C/a>\n\nIf successful, you should see `APPLICATION READY` with a URL. Click the link to open in a new window or tab.","src/content/docs/02_Setup_Application.md","41ac2dedeb3ab62b",{"html":40,"metadata":41},"\u003Cblockquote>\n\u003Cp>Note: Please make sure to redeem the coupon code to your Vonage account’s \u003Ca href=\"https://dashboard.vonage.com/coupons\" target=\"_blank\">dashboard\u003C/a> before continuing. It is needed to purchase a phone number.\u003C/p>\n\u003C/blockquote>\n\u003Cp>In the terminal below, you should see a set up script running asking for your \u003Ccode dir=\"auto\">API key\u003C/code>. Complete the steps in the set up script. This will create an Application with Voice functionality, purchase a phone number, and create the needed Webhook endpoints.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Note: You can get your credentials in the \u003Ca href=\"https://dashboard.vonage.com/settings\" target=\"_blank\">Vonage dashboard Settings Page\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cp>If successful, you should see \u003Ccode dir=\"auto\">APPLICATION READY\u003C/code> with a URL. Click the link to open in a new window or tab.\u003C/p>",{"headings":42,"localImagePaths":43,"remoteImagePaths":44,"frontmatter":45,"imagePaths":46},[],[],[],{"title":30,"description":31},[],"01_create_account",{"id":47,"data":49,"body":55,"filePath":56,"digest":57,"rendered":58},{"title":50,"description":51,"editUrl":16,"head":52,"template":33,"sidebar":53,"pagefind":16,"draft":23},"Create an Account","Create a Vonage account.",[],{"hidden":23,"attrs":54},{},"First, a Vonage account is needed to get the credentials to set up this workshop applications. You can sign up for your account here: \u003Ca href=\"https://dashboard.vonage.com\" target=\"_blank\">Vonage dashboard\u003C/a>\n\nHere's a coupon to add money to your account:\n\nIf your account is in US dollars:\n\n```html\nTorcWebUS2026\n```\n\nIf your account is in Euros:\n\n```html\nTorcWebEUR2026\n```\n\n> Note: Make sure to copy your API Key and API Secret somewhere. We will need it in the next step.","src/content/docs/01_Create_Account.md","0434ab7976c6a491",{"html":59,"metadata":60},"\u003Cp>First, a Vonage account is needed to get the credentials to set up this workshop applications. You can sign up for your account here: \u003Ca href=\"https://dashboard.vonage.com\" target=\"_blank\">Vonage dashboard\u003C/a>\u003C/p>\n\u003Cp>Here’s a coupon to add money to your account:\u003C/p>\n\u003Cp>If your account is in US dollars:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">TorcWebUS2026\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"TorcWebUS2026\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>If your account is in Euros:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">TorcWebEUR2026\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"TorcWebEUR2026\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Note: Make sure to copy your API Key and API Secret somewhere. We will need it in the next step.\u003C/p>\n\u003C/blockquote>",{"headings":61,"localImagePaths":62,"remoteImagePaths":63,"frontmatter":64,"imagePaths":65},[],[],[],{"title":50,"description":51},[],"03_add_client_sdk",{"id":66,"data":68,"body":74,"filePath":75,"digest":76,"rendered":77},{"title":69,"description":70,"editUrl":16,"head":71,"template":33,"sidebar":72,"pagefind":16,"draft":23},"Add Client SDK","Add Vonage Client SDK to index.html",[],{"hidden":23,"attrs":73},{},"We'll be creating a WebXR application using \u003Ca href=\"https://xrblocks.github.io\" target=\"_blank\">XR Blocks\u003C/a> that can answer phone calls.\n\nThe following code will be placed in the `index.html` file.\n\nFirst, we will need to load the Vonage Client SDK from a CDN (`\u003C!-- ⌄⌄⌄ Load the Vonage Client SDK ⌄⌄⌄ -->`):\n```html\n\u003Cscript src=\"https://cdn.jsdelivr.net/npm/@vonage/client-sdk@latest/dist/vonageClientSDK.min.js\">\u003C/script>\n```\n\n> Note: You can also install the Client SDK and point to the nodes module folder if you are using a bundler.\n\n## That's it for the HTML!\n\nEverything else will be handled by XR Blocks.","src/content/docs/03_Add_Client_SDK.md","77c79f191f661eb3",{"html":78,"metadata":79},"\u003Cp>We’ll be creating a WebXR application using \u003Ca href=\"https://xrblocks.github.io\" target=\"_blank\">XR Blocks\u003C/a> that can answer phone calls.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">index.html\u003C/code> file.\u003C/p>\n\u003Cp>First, we will need to load the Vonage Client SDK from a CDN (\u003Ccode dir=\"auto\"><!-- ⌄⌄⌄ Load the Vonage Client SDK ⌄⌄⌄ -->\u003C/code>):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">script\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">src\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://cdn.jsdelivr.net/npm/@vonage/client-sdk@latest/dist/vonageClientSDK.min.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\">></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">script\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript src="https://cdn.jsdelivr.net/npm/@vonage/client-sdk@latest/dist/vonageClientSDK.min.js">\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Note: You can also install the Client SDK and point to the nodes module folder if you are using a bundler.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"thats-it-for-the-html\">That’s it for the HTML!\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#thats-it-for-the-html\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “That’s it for the HTML!”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Everything else will be handled by XR Blocks.\u003C/p>",{"headings":80,"localImagePaths":85,"remoteImagePaths":86,"frontmatter":87,"imagePaths":88},[81],{"depth":82,"slug":83,"text":84},2,"thats-it-for-the-html","That’s it for the HTML!",[],[],{"title":69,"description":70},[],"04_vonage_call_panel",{"id":89,"data":91,"body":97,"filePath":98,"digest":99,"rendered":100},{"title":92,"description":93,"editUrl":16,"head":94,"template":33,"sidebar":95,"pagefind":16,"draft":23},"Vonage Call Panel","Create XR Blocks UI to answer phone calls",[],{"hidden":23,"attrs":96},{},"Now, we'll be creating the UI.\n\nTo recieve phone calls via the Vonage Voice API using the XR Blocks library's \u003Ca href=\"https://xrblocks.github.io/docs/api/classes/SpatialPanel/\" target=\"_blank\">SpatialPanel Class\u003C/a>.\n\nTo show the 3D Avatar for the caller, we will use the \u003Ca href=\"https://xrblocks.github.io/docs/manual/Lipsync/\" target=\"_blank\">Lipsync (Addon)\u003C/a>.\n\nThe Vonage Voice Client SDK's \u003Ca href=\"https://developer.vonage.com/en/vonage-client-sdk/in-app-voice/guides/say-call\" target=\"_blank\">Text to Speech\u003C/a> will be used to send the quick replies and typed messages into the call.\n\nThe virtual keyboard that allows us to type those messages will come from the \u003Ca href=\"https://xrblocks.github.io/docs/manual/UI/#virtual-keyboard-addon\" target=\"_blank\">Virtual Keyboard (Addon)\u003C/a>.\n\nThe following code will be placed in the `VonageAudioCall.js` file.\n\nFirst, we will set the Quick Replies that the user can send into the call.\nFind `// ⌄⌄⌄ Set Quick Replies ⌄⌄⌄` and add this code:\n\n```js\nconst QUICK_REPLIES = [\n { label: \"Meeting\", message: \"In a meeting, I'll call you back.\" },\n { label: \"Talk Later\", message: \"Can't talk right now. I'll talk later.\" },\n { label: \"OMW!\", message: \"On my way! Talk soon.\" },\n { label: \"5 Mins\", message: \"Call you back in 5 minutes.\" },\n];\n```\n\nLet's initiate the constructor for our panel with some variables:\n`// ⌄⌄⌄ Create constructor ⌄⌄⌄`\n\n```js\nconstructor() {\n super();\n this.token = '';\n this.client = new vonageClientSDK.VonageClient();\n this.callId = null;\n // Keep a reference to the panel so we can destroy it later\n this.panel = null;\n this.statusText = null;\n this.userName = \"XR_User_1\";\n this.grid = null;\n this.controlRow = null;\n this.puppetHead = null;\n this.face = null;\n this.mouth = null;\n this._camWorld = new THREE.Vector3();\n this._headWorld = new THREE.Vector3();\n this.replyPanel = null;\n this.typedTextView = null;\n this._currentTypedText = '';\n this.keyboard = null;\n}\n```\n\nHere's the function to create an Avatar and add the MediaStream for the LipSync feature: `// ⌄⌄⌄ Create 3D Avatar ⌄⌄⌄`\n\n```js\n_createAvatar(stream) {\n // Safety: don't create a second avatar if one already exists\n if (this.puppetHead) return;\n\n console.log(\"Creating lipsync avatar...\");\n\n const faceR = 0.1;\n\n const head = new THREE.Group();\n // Position: in front of the user, roughly at face height\n head.position.set(0, xb.user.height, -1.2);\n\n // --- Sphere face mesh ---\n const faceGeom = new THREE.SphereGeometry(faceR, 32, 24);\n const faceMat = new THREE.MeshStandardMaterial({\n color: 0xf2d4b3,\n roughness: 0.6,\n metalness: 0.05,\n });\n const faceMesh = new THREE.Mesh(faceGeom, faceMat);\n head.add(faceMesh);\n\n this.face = new xb.StylizedFace({ showEyes: true });\n head.add(this.face);\n\n this.mouth = new LipsyncMouth(stream, { target: this.face });\n head.add(this.mouth);\n\n this.puppetHead = head;\n this.add(head);\n}\n```\n\nThis function will remove the 3D Avatar when the call is over:\n`// ⌄⌄⌄ Remove 3D Avatar ⌄⌄⌄`\n\n```js\n_removeAvatar() {\n if (!this.puppetHead) return;\n\n console.log(\"Removing lipsync avatar...\");\n\n if (this.mouth) {\n // Detach from the head group before nulling the reference\n this.mouth.parent?.remove(this.mouth);\n this.mouth = null;\n }\n\n if (this.face) {\n this.face.parent?.remove(this.face);\n // dispose() frees the underlying canvas/texture to avoid memory leaks\n this.face.dispose();\n this.face = null;\n }\n\n this.remove(this.puppetHead);\n this.puppetHead = null;\n}\n```\n\nHere's the function to create the panel:\n`// ⌄⌄⌄ Create Call panel ⌄⌄⌄`\n\n```js\n_createCallPanel(callerName) {\n // SAFETY: If a panel already exists, don't create another one.\n if (this.panel) return;\n\n console.log(\"Creating Call UI...\");\n\n // 1. Create the Panel\n this.panel = new xb.SpatialPanel({ backgroundColor: '#2b2b2baa' });\n this.panel.position.set(\n 0,\n xb.user.height - 0.5,\n -xb.user.objectDistance\n );\n\n this.add(this.panel);\n\n this.grid = this.panel.addGrid();\n\n // 2. Status Text\n this.statusText = this.grid.addRow({ weight: 0.7 }).addText({\n text: `Incoming call from ${callerName}...`,\n fontColor: '#ffffff',\n fontSize: 0.08,\n });\n\n this.updateControlRow('INCOMING');\n}\n```\n\nFunction to update the call control section:\n`// ⌄⌄⌄ Update Call controls ⌄⌄⌄`\n\n```js\nupdateControlRow(state) {\n if (!this.grid) return;\n\n // 1. Remove the existing row if it exists\n if (this.controlRow) {\n this.grid.remove(this.controlRow);\n this.controlRow = null;\n this.grid.resetLayout();\n }\n\n // 2. Create a fresh row. It will naturally append below the Status Text.\n // We give it the full remaining weight (0.3 relative to the panel, or flexible)\n this.controlRow = this.grid.addRow({ weight: 0.3 });\n\n if (state === 'INCOMING') {\n // --- ANSWER BUTTON ---\n const answerBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({\n text: 'call',\n fontSize: 0.5,\n backgroundColor: '#00ff00'\n });\n answerBtn.onTriggered = () => this._onAnswer();\n\n // --- REJECT BUTTON ---\n const rejectBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({\n text: 'call_end',\n fontSize: 0.5,\n backgroundColor: '#ff0000'\n });\n rejectBtn.onTriggered = () => this._onReject();\n\n } else if (state === 'CONNECTED') {\n // --- HANGUP BUTTON ---\n // This is a fresh row, so layouts will calculate correctly\n const hangupBtn = this.controlRow.addCol({ weight: 1 }).addIconButton({\n text: 'call_end',\n fontSize: 0.5,\n backgroundColor: '#ff0000'\n });\n hangupBtn.onTriggered = () => this._onHangup();\n }\n\n // 3. Force layout update\n this.panel.updateLayouts();\n}\n```\n\nThis function will remove the panel once the call is over:\n`// ⌄⌄⌄ Remove Call panel ⌄⌄⌄`\n\n```js\n_removeCallPanel() {\n if (this.panel) {\n console.log(\"Destroying Call UI...\");\n this.remove(this.panel);\n this.panel = null;\n this.grid = null;\n this.statusText = null;\n this.controlRow = null;\n }\n this._removeReplyPanel();\n}\n```\n\nNow, let's add the Virtual Keyboard that will allow us to send text messages that will be spoken into the call.\n\nHere's the code to show the Keyboard:\n`// ⌄⌄⌄ Show Virtual Keyboard ⌄⌄⌄`\n\n```js\n_showKeyboard() {\n if (this.keyboard) return;\n\n this.keyboard = new Keyboard();\n // Position it below and aligned with the reply panel\n this.keyboard.position.set(\n 0,\n xb.user.height - 1.35,\n -xb.user.objectDistance + 1\n );\n this.add(this.keyboard);\n\n // Update the display on every keystroke\n this.keyboard.onTextChanged = (text) => {\n this._currentTypedText = text;\n if (this.typedTextView) {\n this.typedTextView.text = text.length > 0 ? text : 'Tap to type...';\n }\n };\n\n // Enter key sends immediately — same as tapping the Send button\n this.keyboard.onEnterPressed = (text) => {\n this._sendTypedText();\n };\n}\n```\n\nIf we want to hide the Keyboard, here's the code:\n`// ⌄⌄⌄ Hide Virtual Keyboard ⌄⌄⌄`\n\n```js\n_hideKeyboard() {\n if (!this.keyboard) return;\n this.remove(this.keyboard);\n this.keyboard = null;\n}\n```\n\nTo toggle between showing and hidding the keyboard, we have this code:\n`// ⌄⌄⌄ Toggle Virtual Keyboard ⌄⌄⌄`\n\n```js\n_toggleKeyboard() {\n this.keyboard ? this._hideKeyboard() : this._showKeyboard();\n}\n```\n\nLet's create the functions that will send the text to be said into the call just in case we can't talk at that moment.\n\nTo send the Quick Replies that we set before:\n`// ⌄⌄⌄ Send Quick Reply ⌄⌄⌄`\n\n```js\n_sendQuickReply(message) {\n if (!this.callId) return;\n console.log(`Sending quick reply: \"${message}\"`);\n\n // Give the user immediate visual feedback in the status bar\n if (this.statusText) this.statusText.text = 'Sending...';\n\n this.client.say(this.callId, message)\n .then(() => {\n console.log('Quick reply sent successfully.');\n if (this.statusText) this.statusText.text = `Sent: \"${message}\"`;\n })\n .catch(err => {\n console.error('say() error:', err);\n if (this.statusText) this.statusText.text = 'Failed to send message.';\n });\n}\n```\n\nIn the case we want to carry on the conversation but maybe can't speak (ie in a public space), we can send custom text:\n`// ⌄⌄⌄ Send Custom Text ⌄⌄⌄`\n\n```js\n_sendTypedText() {\n const text = this._currentTypedText.trim();\n if (!text) return;\n if (!this.callId) return;\n\n console.log(`Sending typed text: \"${text}\"`);\n if (this.statusText) this.statusText.text = 'Sending...';\n\n this.client.say(this.callId, text)\n .then(() => {\n console.log('Typed text sent successfully.');\n if (this.statusText) this.statusText.text = `Sent: \"${text}\"`;\n\n // Clear the keyboard buffer and reset the display\n if (this.keyboard) this.keyboard.setText('');\n this._currentTypedText = '';\n if (this.typedTextView) this.typedTextView.text = 'Tap to type...';\n })\n .catch(err => {\n console.error('say() error:', err);\n if (this.statusText) this.statusText.text = 'Failed to send message.';\n });\n}\n```\n\nHere we will create the Reply panel that will hold all the way we can send a text message into the call:\n`// ⌄⌄⌄ Create Reply panel ⌄⌄⌄`\n\n```js\n_createReplyPanel() {\n if (this.replyPanel) return;\n\n this.replyPanel = new xb.SpatialPanel({\n backgroundColor: '#1a1a2ecc',\n width: .75,\n height: 0.9,\n });\n // Offset to the right so it sits beside the main call panel\n this.replyPanel.position.set(\n 0.8,\n xb.user.height - 0.5,\n -xb.user.objectDistance\n );\n this.add(this.replyPanel);\n\n const grid = this.replyPanel.addGrid();\n\n grid.addRow({ weight: 0.06 }).addText({\n text: 'Quick Replies',\n fontColor: '#9b9bff',\n fontSize: 0.055,\n });\n\n const pairs = [\n QUICK_REPLIES.slice(0, 2), // [ Meeting, Talk Later ]\n QUICK_REPLIES.slice(2, 4), // [ OMW!, 5 Mins ]\n ];\n\n pairs.forEach(pair => {\n const row = grid.addRow({ weight: 0.20 });\n pair.forEach(({ label, message }) => {\n const btn = row.addCol({ weight: 0.5 }).addTextButton({\n text: label,\n fontSize: 0.35,\n backgroundColor: '#2e2e50',\n fontColor: '#ffffff',\n });\n btn.onTriggered = () => this._sendQuickReply(message);\n });\n });\n\n grid.addRow({ weight: 0.06 }).addText({\n text: 'Talk via Text',\n fontColor: '#9b9bff',\n fontSize: 0.055,\n });\n\n this.typedTextView = grid.addRow({ weight: 0.18 }).addText({\n text: 'Tap to type...',\n fontColor: '#ffffff',\n fontSize: 0.065,\n textAlign: 'left',\n });\n\n const actionRow = grid.addRow({ weight: 0.30 });\n\n const kbBtn = actionRow.addCol({ weight: 0.5 }).addIconButton({\n text: 'keyboard',\n fontSize: 0.5,\n backgroundColor: '#2e3a4a',\n });\n kbBtn.onTriggered = () => this._toggleKeyboard();\n\n const sendBtn = actionRow.addCol({ weight: 0.5 }).addIconButton({\n text: 'send',\n fontSize: 0.5,\n backgroundColor: '#1a4a2a',\n });\n sendBtn.onTriggered = () => this._sendTypedText();\n\n this.replyPanel.updateLayouts();\n}\n```\n\nJust like with the Call panel, we will have a function to remove the Reply panel:\n`// ⌄⌄⌄ Remove Reply panel ⌄⌄⌄`\n\n```js\n_removeReplyPanel() {\n this._hideKeyboard();\n if (this.replyPanel) {\n this.remove(this.replyPanel);\n this.replyPanel = null;\n this.typedTextView = null;\n }\n this._currentTypedText = '';\n}\n```\n\nThis function answers the call and updates the status and call control section:\n`// ⌄⌄⌄ Answer call method ⌄⌄⌄`\n\n```js\n_onAnswer() {\n console.log('Answering...');\n this.client.answer(this.callId)\n .then(() => {\n console.log(\"Success answering call.\");\n this.statusText.text = `Call answered.`;\n this.updateControlRow('CONNECTED');\n\n // ⌄⌄⌄ Show reply panel alongside the call panel ⌄⌄⌄\n this._createReplyPanel();\n\n // get media stream\n const audioElement = this.client.getAudioOutputElement();\n if (audioElement && audioElement.srcObject) {\n // This is the active WebRTC MediaStream managed by Vonage\n const remoteStream = audioElement.srcObject;\n console.log('remoteStream: ', remoteStream);\n\n // Example: Grab individual audio tracks from the stream\n const audioTracks = remoteStream.getAudioTracks();\n console.log(\"Active Audio Tracks:\", audioTracks);\n\n // ⌄⌄⌄ Spin up the lipsync avatar driven by the remote stream ⌄⌄⌄\n this._createAvatar(remoteStream);\n }\n })\n .catch(error => {\n console.error(\"Error answering call: \", error);\n });\n}\n```\n\nThis function will reject the incoming call and remove the panel:\n`// ⌄⌄⌄ Reject call method ⌄⌄⌄`\n\n```js\n_onReject() {\n console.log('Rejecting...');\n this.client.reject(this.callId)\n .then(() => {\n console.log(\"Success rejecting call.\");\n })\n .catch(error => {\n console.error(\"Error rejecting call: \", error);\n });\n this._removeCallPanel();\n this._removeAvatar();\n}\n```\n\nThis function will hang up the ongoing call and remove the panel:\n`// ⌄⌄⌄ Hang Up call method ⌄⌄⌄ `\n\n```js\n_onHangup() {\n console.log('Hanging up...');\n this.client.hangup(this.callId)\n .then(() => {\n console.log(\"Success hanging up call.\");\n })\n .catch(error => {\n console.error(\"Error hanging up call: \", error);\n });\n // We manually destroy the panel here too, just in case the event lags\n this._removeCallPanel();\n this._removeAvatar();\n}\n```\n\nSet up some listeners for the events that the Vonage Client SDK will emit and what to do:\n`// ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄`\n\n```js\nsetupVonageListeners() {\n // --- CREATE UI ON INVITE ---\n this.client.on('callInvite', (callId, from, channelType) => {\n this.callId = callId;\n const maskedNumber = from.replace(/\\d(?=(?:\\D*\\d){4})/g, \"*\")\n console.log(`Incoming call from ${maskedNumber}`);\n\n // Trigger the UI creation here\n this._createCallPanel(maskedNumber);\n });\n\n this.client.on('legStatusUpdate', (callId, legId, status) => {\n console.log(\"status: \", status);\n if (this.statusText) {\n this.statusText.text = `Status: ${status}`;\n }\n });\n\n // --- REMOVE UI ON CANCEL/HANGUP ---\n this.client.on('callInviteCancel', (callId) => {\n console.log(`Call cancelled: ${callId}`);\n this.callId = null;\n this._removeCallPanel();\n this._removeAvatar();\n });\n\n this.client.on(\"callHangup\", (callId, callQuality, reason) => {\n console.log(`Call hung up: ${reason}`);\n this.callId = null;\n this._removeCallPanel();\n this._removeAvatar();\n });\n}\n```\n\nGet a token from the server so you can connect to a session:\n`// ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ `\n\n```js\nasync connectToVonage(name) {\n try {\n console.log(`Fetching token for ${name}...`);\n\n // 1. Fetch the token (AWAIT the result)\n const response = await fetch(`/token?name=${name}`);\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data = await response.json();\n this.token = data.token;\n console.log(\"Fetched token successfully.\");\n\n // 2. Create the Session (AWAIT the result)\n const sessionId = await this.client.createSession(this.token);\n\n console.log(\"Session created successfully. Session ID:\", sessionId);\n\n // 3. Update UI\n // Instead, update your XR Panel text to show we are ready\n if(this.statusText) {\n this.statusText.text = \"Connected. Waiting for calls...\";\n }\n\n } catch (error) {\n console.error(\"Connection failed:\", error);\n if(this.statusText) this.statusText.text = \"Connection Failed.\";\n }\n}\n```\n\nInitialize the Class when loaded into the page:\n`// ⌄⌄⌄ Initialize ⌄⌄⌄`\n\n```js\ninit() {\n console.log(\"Vonage init!\",this.client);\n this.setupVonageListeners();\n this.connectToVonage(this.userName);\n}\n```","src/content/docs/04_Vonage_Call_Panel.md","35a9af8a8ca7718e",{"html":101,"metadata":102},"\u003Cp>Now, we’ll be creating the UI.\u003C/p>\n\u003Cp>To recieve phone calls via the Vonage Voice API using the XR Blocks library’s \u003Ca href=\"https://xrblocks.github.io/docs/api/classes/SpatialPanel/\" target=\"_blank\">SpatialPanel Class\u003C/a>.\u003C/p>\n\u003Cp>To show the 3D Avatar for the caller, we will use the \u003Ca href=\"https://xrblocks.github.io/docs/manual/Lipsync/\" target=\"_blank\">Lipsync (Addon)\u003C/a>.\u003C/p>\n\u003Cp>The Vonage Voice Client SDK’s \u003Ca href=\"https://developer.vonage.com/en/vonage-client-sdk/in-app-voice/guides/say-call\" target=\"_blank\">Text to Speech\u003C/a> will be used to send the quick replies and typed messages into the call.\u003C/p>\n\u003Cp>The virtual keyboard that allows us to type those messages will come from the \u003Ca href=\"https://xrblocks.github.io/docs/manual/UI/#virtual-keyboard-addon\" target=\"_blank\">Virtual Keyboard (Addon)\u003C/a>.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">VonageAudioCall.js\u003C/code> file.\u003C/p>\n\u003Cp>First, we will set the Quick Replies that the user can send into the call.\nFind \u003Ccode dir=\"auto\">// ⌄⌄⌄ Set Quick Replies ⌄⌄⌄\u003C/code> and add this code:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">QUICK_REPLIES\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> =\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ label: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Meeting\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, message: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">In a meeting, I'll call you back.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ label: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Talk Later\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, message: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Can't talk right now. I'll talk later.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ label: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">OMW!\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, message: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">On my way! Talk soon.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ label: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">5 Mins\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, message: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Call you back in 5 minutes.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">];\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const QUICK_REPLIES = [ { label: "Meeting", message: "In a meeting, I'll call you back." }, { label: "Talk Later", message: "Can't talk right now. I'll talk later." }, { label: "OMW!", message: "On my way! Talk soon." }, { label: "5 Mins", message: "Call you back in 5 minutes." },];\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Let’s initiate the constructor for our panel with some variables:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create constructor ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">constructor\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">super\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">vonageClientSDK\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">VonageClient\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Keep a reference to the panel so we can destroy it later\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">userName\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">XR_User_1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">puppetHead\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mouth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">_camWorld\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">THREE\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Vector3\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">_headWorld\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">THREE\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Vector3\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">typedTextView\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">_currentTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"constructor() { super(); this.token = ''; this.client = new vonageClientSDK.VonageClient(); this.callId = null; // Keep a reference to the panel so we can destroy it later this.panel = null; this.statusText = null; this.userName = "XR_User_1"; this.grid = null; this.controlRow = null; this.puppetHead = null; this.face = null; this.mouth = null; this._camWorld = new THREE.Vector3(); this._headWorld = new THREE.Vector3(); this.replyPanel = null; this.typedTextView = null; this._currentTypedText = ''; this.keyboard = null;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Here’s the function to create an Avatar and add the MediaStream for the LipSync feature: \u003Ccode dir=\"auto\">// ⌄⌄⌄ Create 3D Avatar ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_createAvatar\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">stream\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Safety: don't create a second avatar if one already exists\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">puppetHead\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Creating lipsync avatar...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">faceR\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">head\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">THREE\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Position: in front of the user, roughly at face height\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">head\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- Sphere face mesh ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">faceGeom\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">THREE\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">SphereGeometry\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">faceR\u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">32\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">24\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">faceMat\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">THREE\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">MeshStandardMaterial\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">color: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0xf2d4b3\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">roughness: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.6\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">metalness: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.05\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">faceMesh\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">THREE\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Mesh\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">faceGeom\u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">faceMat\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">head\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">faceMesh\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">StylizedFace\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ showEyes: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">head\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mouth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">LipsyncMouth\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">stream\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, { target: \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">head\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mouth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">puppetHead\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">head\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">;\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">head\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_createAvatar(stream) { // Safety: don't create a second avatar if one already exists if (this.puppetHead) return; console.log("Creating lipsync avatar..."); const faceR = 0.1; const head = new THREE.Group(); // Position: in front of the user, roughly at face height head.position.set(0, xb.user.height, -1.2); // --- Sphere face mesh --- const faceGeom = new THREE.SphereGeometry(faceR, 32, 24); const faceMat = new THREE.MeshStandardMaterial({ color: 0xf2d4b3, roughness: 0.6, metalness: 0.05, }); const faceMesh = new THREE.Mesh(faceGeom, faceMat); head.add(faceMesh); this.face = new xb.StylizedFace({ showEyes: true }); head.add(this.face); this.mouth = new LipsyncMouth(stream, { target: this.face }); head.add(this.mouth); this.puppetHead = head; this.add(head);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will remove the 3D Avatar when the call is over:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Remove 3D Avatar ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeAvatar\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">puppetHead\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Removing lipsync avatar...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mouth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Detach from the head group before nulling the reference\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">mouth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">parent\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mouth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mouth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">face\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">parent\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// dispose() frees the underlying canvas/texture to avoid memory leaks\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">face\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">dispose\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">puppetHead\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">puppetHead\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_removeAvatar() { if (!this.puppetHead) return; console.log("Removing lipsync avatar..."); if (this.mouth) { // Detach from the head group before nulling the reference this.mouth.parent?.remove(this.mouth); this.mouth = null; } if (this.face) { this.face.parent?.remove(this.face); // dispose() frees the underlying canvas/texture to avoid memory leaks this.face.dispose(); this.face = null; } this.remove(this.puppetHead); this.puppetHead = null;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Here’s the function to create the panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create Call panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_createCallPanel\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">callerName\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// SAFETY: If a panel already exists, don't create another one.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Creating Call UI...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Create the Panel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">SpatialPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#2b2b2baa\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">objectDistance\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addGrid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Status Text\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.7\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Incoming call from \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">callerName\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ffffff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.08\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateControlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">INCOMING\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_createCallPanel(callerName) { // SAFETY: If a panel already exists, don't create another one. if (this.panel) return; console.log("Creating Call UI..."); // 1. Create the Panel this.panel = new xb.SpatialPanel({ backgroundColor: '#2b2b2baa' }); this.panel.position.set( 0, xb.user.height - 0.5, -xb.user.objectDistance ); this.add(this.panel); this.grid = this.panel.addGrid(); // 2. Status Text this.statusText = this.grid.addRow({ weight: 0.7 }).addText({ text: `Incoming call from ${callerName}...`, fontColor: '#ffffff', fontSize: 0.08, }); this.updateControlRow('INCOMING');}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Function to update the call control section:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Update Call controls ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateControlRow\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">state\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Remove the existing row if it exists\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">resetLayout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Create a fresh row. It will naturally append below the Status Text.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// We give it the full remaining weight (0.3 relative to the panel, or flexible)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.3\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">state\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">INCOMING\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- ANSWER BUTTON ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">answerBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">controlRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">call\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#00ff00\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">answerBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onAnswer\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- REJECT BUTTON ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">rejectBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">controlRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">call_end\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ff0000\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">rejectBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onReject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">else\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">state\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">CONNECTED\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- HANGUP BUTTON ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// This is a fresh row, so layouts will calculate correctly\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hangupBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">controlRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">call_end\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ff0000\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">hangupBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onHangup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 3. Force layout update\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateLayouts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"updateControlRow(state) { if (!this.grid) return; // 1. Remove the existing row if it exists if (this.controlRow) { this.grid.remove(this.controlRow); this.controlRow = null; this.grid.resetLayout(); } // 2. Create a fresh row. It will naturally append below the Status Text. // We give it the full remaining weight (0.3 relative to the panel, or flexible) this.controlRow = this.grid.addRow({ weight: 0.3 }); if (state === 'INCOMING') { // --- ANSWER BUTTON --- const answerBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({ text: 'call', fontSize: 0.5, backgroundColor: '#00ff00' }); answerBtn.onTriggered = () => this._onAnswer(); // --- REJECT BUTTON --- const rejectBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({ text: 'call_end', fontSize: 0.5, backgroundColor: '#ff0000' }); rejectBtn.onTriggered = () => this._onReject(); } else if (state === 'CONNECTED') { // --- HANGUP BUTTON --- // This is a fresh row, so layouts will calculate correctly const hangupBtn = this.controlRow.addCol({ weight: 1 }).addIconButton({ text: 'call_end', fontSize: 0.5, backgroundColor: '#ff0000' }); hangupBtn.onTriggered = () => this._onHangup(); } // 3. Force layout update this.panel.updateLayouts();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will remove the panel once the call is over:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Remove Call panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Destroying Call UI...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeReplyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_removeCallPanel() { if (this.panel) { console.log("Destroying Call UI..."); this.remove(this.panel); this.panel = null; this.grid = null; this.statusText = null; this.controlRow = null; } this._removeReplyPanel();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Now, let’s add the Virtual Keyboard that will allow us to send text messages that will be spoken into the call.\u003C/p>\n\u003Cp>Here’s the code to show the Keyboard:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Show Virtual Keyboard ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_showKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Position it below and aligned with the reply panel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">keyboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.35\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">objectDistance\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">+\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Update the display on every keystroke\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">keyboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTextChanged\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">text\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">_currentTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">;\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">typedTextView\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">typedTextView\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">length\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Tap to type...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Enter key sends immediately — same as tapping the Send button\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">keyboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onEnterPressed\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">text\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_sendTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_showKeyboard() { if (this.keyboard) return; this.keyboard = new Keyboard(); // Position it below and aligned with the reply panel this.keyboard.position.set( 0, xb.user.height - 1.35, -xb.user.objectDistance + 1 ); this.add(this.keyboard); // Update the display on every keystroke this.keyboard.onTextChanged = (text) => { this._currentTypedText = text; if (this.typedTextView) { this.typedTextView.text = text.length > 0 ? text : 'Tap to type...'; } }; // Enter key sends immediately — same as tapping the Send button this.keyboard.onEnterPressed = (text) => { this._sendTypedText(); };}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>If we want to hide the Keyboard, here’s the code:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Hide Virtual Keyboard ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_hideKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_hideKeyboard() { if (!this.keyboard) return; this.remove(this.keyboard); this.keyboard = null;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>To toggle between showing and hidding the keyboard, we have this code:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Toggle Virtual Keyboard ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_toggleKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_hideKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_showKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_toggleKeyboard() { this.keyboard ? this._hideKeyboard() : this._showKeyboard();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Let’s create the functions that will send the text to be said into the call just in case we can’t talk at that moment.\u003C/p>\n\u003Cp>To send the Quick Replies that we set before:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Send Quick Reply ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_sendQuickReply\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">message\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Sending quick reply: \"\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">message\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Give the user immediate visual feedback in the status bar\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Sending...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">say\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">message\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">)\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Quick reply sent successfully.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Sent: \"\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">message\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">err\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">say() error:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">err\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Failed to send message.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_sendQuickReply(message) { if (!this.callId) return; console.log(`Sending quick reply: "${message}"`); // Give the user immediate visual feedback in the status bar if (this.statusText) this.statusText.text = 'Sending...'; this.client.say(this.callId, message) .then(() => { console.log('Quick reply sent successfully.'); if (this.statusText) this.statusText.text = `Sent: "${message}"`; }) .catch(err => { console.error('say() error:', err); if (this.statusText) this.statusText.text = 'Failed to send message.'; });}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>In the case we want to carry on the conversation but maybe can’t speak (ie in a public space), we can send custom text:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Send Custom Text ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_sendTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">text\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">_currentTypedText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">trim\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Sending typed text: \"\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">text\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Sending...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">say\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">)\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Typed text sent successfully.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Sent: \"\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">text\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Clear the keyboard buffer and reset the display\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">keyboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">_currentTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">typedTextView\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">typedTextView\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Tap to type...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">err\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">say() error:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">err\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Failed to send message.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_sendTypedText() { const text = this._currentTypedText.trim(); if (!text) return; if (!this.callId) return; console.log(`Sending typed text: "${text}"`); if (this.statusText) this.statusText.text = 'Sending...'; this.client.say(this.callId, text) .then(() => { console.log('Typed text sent successfully.'); if (this.statusText) this.statusText.text = `Sent: "${text}"`; // Clear the keyboard buffer and reset the display if (this.keyboard) this.keyboard.setText(''); this._currentTypedText = ''; if (this.typedTextView) this.typedTextView.text = 'Tap to type...'; }) .catch(err => { console.error('say() error:', err); if (this.statusText) this.statusText.text = 'Failed to send message.'; });}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Here we will create the Reply panel that will hold all the way we can send a text message into the call:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create Reply panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_createReplyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">SpatialPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#1a1a2ecc\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">width: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">.75\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">height: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.9\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Offset to the right so it sits beside the main call panel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">replyPanel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.8\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">objectDistance\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">replyPanel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addGrid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.06\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Quick Replies\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#9b9bff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.055\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pairs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> =\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">QUICK_REPLIES\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">slice\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">), \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// [ Meeting, Talk Later ]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">QUICK_REPLIES\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">slice\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">4\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">), \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// [ OMW!, 5 Mins ]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">pairs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">forEach\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">pair\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">row\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.20\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">pair\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">forEach\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">{ \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">label\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">message\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> }\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">btn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">row\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addTextButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">label\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.35\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#2e2e50\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ffffff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">btn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_sendQuickReply\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">message\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.06\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Talk via Text\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#9b9bff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.055\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">typedTextView\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.18\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Tap to type...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ffffff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.065\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">textAlign: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">left\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">actionRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.30\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">kbBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">actionRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">keyboard\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#2e3a4a\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">kbBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_toggleKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sendBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">actionRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">send\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#1a4a2a\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">sendBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_sendTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">replyPanel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateLayouts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_createReplyPanel() { if (this.replyPanel) return; this.replyPanel = new xb.SpatialPanel({ backgroundColor: '#1a1a2ecc', width: .75, height: 0.9, }); // Offset to the right so it sits beside the main call panel this.replyPanel.position.set( 0.8, xb.user.height - 0.5, -xb.user.objectDistance ); this.add(this.replyPanel); const grid = this.replyPanel.addGrid(); grid.addRow({ weight: 0.06 }).addText({ text: 'Quick Replies', fontColor: '#9b9bff', fontSize: 0.055, }); const pairs = [ QUICK_REPLIES.slice(0, 2), // [ Meeting, Talk Later ] QUICK_REPLIES.slice(2, 4), // [ OMW!, 5 Mins ] ]; pairs.forEach(pair => { const row = grid.addRow({ weight: 0.20 }); pair.forEach(({ label, message }) => { const btn = row.addCol({ weight: 0.5 }).addTextButton({ text: label, fontSize: 0.35, backgroundColor: '#2e2e50', fontColor: '#ffffff', }); btn.onTriggered = () => this._sendQuickReply(message); }); }); grid.addRow({ weight: 0.06 }).addText({ text: 'Talk via Text', fontColor: '#9b9bff', fontSize: 0.055, }); this.typedTextView = grid.addRow({ weight: 0.18 }).addText({ text: 'Tap to type...', fontColor: '#ffffff', fontSize: 0.065, textAlign: 'left', }); const actionRow = grid.addRow({ weight: 0.30 }); const kbBtn = actionRow.addCol({ weight: 0.5 }).addIconButton({ text: 'keyboard', fontSize: 0.5, backgroundColor: '#2e3a4a', }); kbBtn.onTriggered = () => this._toggleKeyboard(); const sendBtn = actionRow.addCol({ weight: 0.5 }).addIconButton({ text: 'send', fontSize: 0.5, backgroundColor: '#1a4a2a', }); sendBtn.onTriggered = () => this._sendTypedText(); this.replyPanel.updateLayouts();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Just like with the Call panel, we will have a function to remove the Reply panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Remove Reply panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeReplyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_hideKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">typedTextView\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">_currentTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_removeReplyPanel() { this._hideKeyboard(); if (this.replyPanel) { this.remove(this.replyPanel); this.replyPanel = null; this.typedTextView = null; } this._currentTypedText = '';}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function answers the call and updates the status and call control section:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Answer call method ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onAnswer\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Answering...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">answer\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Success answering call.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Call answered.\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateControlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">CONNECTED\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ⌄⌄⌄ Show reply panel alongside the call panel ⌄⌄⌄\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_createReplyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// get media stream\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">audioElement\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getAudioOutputElement\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">audioElement\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">audioElement\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">srcObject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// This is the active WebRTC MediaStream managed by Vonage\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remoteStream\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">audioElement\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">srcObject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">remoteStream: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">remoteStream\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Example: Grab individual audio tracks from the stream\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">audioTracks\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">remoteStream\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getAudioTracks\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Active Audio Tracks:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">audioTracks\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ⌄⌄⌄ Spin up the lipsync avatar driven by the remote stream ⌄⌄⌄\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_createAvatar\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">remoteStream\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Error answering call: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_onAnswer() { console.log('Answering...'); this.client.answer(this.callId) .then(() => { console.log("Success answering call."); this.statusText.text = `Call answered.`; this.updateControlRow('CONNECTED'); // ⌄⌄⌄ Show reply panel alongside the call panel ⌄⌄⌄ this._createReplyPanel(); // get media stream const audioElement = this.client.getAudioOutputElement(); if (audioElement && audioElement.srcObject) { // This is the active WebRTC MediaStream managed by Vonage const remoteStream = audioElement.srcObject; console.log('remoteStream: ', remoteStream); // Example: Grab individual audio tracks from the stream const audioTracks = remoteStream.getAudioTracks(); console.log("Active Audio Tracks:", audioTracks); // ⌄⌄⌄ Spin up the lipsync avatar driven by the remote stream ⌄⌄⌄ this._createAvatar(remoteStream); } }) .catch(error => { console.error("Error answering call: ", error); });}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will reject the incoming call and remove the panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Reject call method ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onReject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Rejecting...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">reject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Success rejecting call.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Error rejecting call: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeAvatar\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_onReject() { console.log('Rejecting...'); this.client.reject(this.callId) .then(() => { console.log("Success rejecting call."); }) .catch(error => { console.error("Error rejecting call: ", error); }); this._removeCallPanel(); this._removeAvatar();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will hang up the ongoing call and remove the panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Hang Up call method ⌄⌄⌄ \u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onHangup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Hanging up...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hangup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Success hanging up call.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Error hanging up call: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// We manually destroy the panel here too, just in case the event lags\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeAvatar\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_onHangup() { console.log('Hanging up...'); this.client.hangup(this.callId) .then(() => { console.log("Success hanging up call."); }) .catch(error => { console.error("Error hanging up call: ", error); }); // We manually destroy the panel here too, just in case the event lags this._removeCallPanel(); this._removeAvatar();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Set up some listeners for the events that the Vonage Client SDK will emit and what to do:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setupVonageListeners\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- CREATE UI ON INVITE ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">callInvite\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">channelType\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">;\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">maskedNumber\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">from\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">replace\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">/\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">\\d\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">(?=(?:\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">\\D\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">\\d\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">{4}\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">)\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">/\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">g\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">*\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Incoming call from \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">maskedNumber\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Trigger the UI creation here\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_createCallPanel\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">maskedNumber\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">legStatusUpdate\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">legId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">status\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">status: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">status\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Status: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">status\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- REMOVE UI ON CANCEL/HANGUP ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">callInviteCancel\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">callId\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Call cancelled: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">callId\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeAvatar\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">callHangup\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">callQuality\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">reason\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Call hung up: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">reason\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeAvatar\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"setupVonageListeners() { // --- CREATE UI ON INVITE --- this.client.on('callInvite', (callId, from, channelType) => { this.callId = callId; const maskedNumber = from.replace(/\\d(?=(?:\\D*\\d){4})/g, "*") console.log(`Incoming call from ${maskedNumber}`); // Trigger the UI creation here this._createCallPanel(maskedNumber); }); this.client.on('legStatusUpdate', (callId, legId, status) => { console.log("status: ", status); if (this.statusText) { this.statusText.text = `Status: ${status}`; } }); // --- REMOVE UI ON CANCEL/HANGUP --- this.client.on('callInviteCancel', (callId) => { console.log(`Call cancelled: ${callId}`); this.callId = null; this._removeCallPanel(); this._removeAvatar(); }); this.client.on("callHangup", (callId, callQuality, reason) => { console.log(`Call hung up: ${reason}`); this.callId = null; this._removeCallPanel(); this._removeAvatar(); });}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Get a token from the server so you can connect to a session:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ \u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">async\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">connectToVonage\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">name\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">try\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Fetching token for \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">name\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Fetch the token (AWAIT the result)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fetch\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">/token?name=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">name\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">ok\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">throw\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">HTTP error! status: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">status\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">json\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Fetched token successfully.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Create the Session (AWAIT the result)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sessionId\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createSession\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Session created successfully. Session ID:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">sessionId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 3. Update UI\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Instead, update your XR Panel text to show we are ready\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Connected. Waiting for calls...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Connection failed:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Connection Failed.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"async connectToVonage(name) { try { console.log(`Fetching token for ${name}...`); // 1. Fetch the token (AWAIT the result) const response = await fetch(`/token?name=${name}`); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); this.token = data.token; console.log("Fetched token successfully."); // 2. Create the Session (AWAIT the result) const sessionId = await this.client.createSession(this.token); console.log("Session created successfully. Session ID:", sessionId); // 3. Update UI // Instead, update your XR Panel text to show we are ready if(this.statusText) { this.statusText.text = "Connected. Waiting for calls..."; } } catch (error) { console.error("Connection failed:", error); if(this.statusText) this.statusText.text = "Connection Failed."; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Initialize the Class when loaded into the page:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Initialize ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">init\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Vonage init!\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setupVonageListeners\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">connectToVonage\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">userName\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"init() { console.log("Vonage init!",this.client); this.setupVonageListeners(); this.connectToVonage(this.userName);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":103,"localImagePaths":104,"remoteImagePaths":105,"frontmatter":106,"imagePaths":107},[],[],[],{"title":92,"description":93},[],"05_exit_button",{"id":108,"data":110,"body":116,"filePath":117,"digest":118,"rendered":119},{"title":111,"description":112,"editUrl":16,"head":113,"template":33,"sidebar":114,"pagefind":16,"draft":23},"Exiting WebXR application","Button to exit WebXR application",[],{"hidden":23,"attrs":115},{},"When in the WebXR environment using a headset, I could not figure out how to leave the experience, so I made an Exit Demo Panel.\n\nThe following code will be placed in the `ExitButton.js` file.\n\nCreate the constructor for the Class:\n`// ⌄⌄⌄ Create constructor ⌄⌄⌄`\n```js\n constructor() {\n super();\n // Keep a reference to the panel so we can destroy it later\n this.panel = null; \n this.statusText = null;\n this.exitPanelText = \"Exit Demo\";\n }\n```\n\nFunction to create a panel for the Exit Button:\n`// ⌄⌄⌄ Create Exit Button panel ⌄⌄⌄`\n```js\n createExitPanel() {\n // SAFETY: If a panel already exists, don't create another one.\n if (this.panel) return;\n\n console.log(\"Creating Exit Button...\");\n \n // 1. Create the Panel\n this.panel = new xb.SpatialPanel({\n width: 0.5,\n height: 0.5, \n backgroundColor: '#2b2b2baa'\n });\n\n this.panel.position.set(\n 0,\n xb.user.height,\n 2.0\n );\n\n this.panel.rotation.set(0, Math.PI, 0);\n this.add(this.panel);\n\n const grid = this.panel.addGrid();\n\n // 2. Status Text\n this.statusText = grid.addRow({ weight: 1 }).addText({\n text: this.exitPanelText,\n fontColor: '#ffffff',\n fontSize: .4,\n });\n\n // Orbiter\n const orbiter = grid.addOrbiter();\n orbiter.addExitButton();\n this.panel.updateLayouts();\n }\n```\n\nInitialize Class when loaded into the page:\n`// ⌄⌄⌄ Initialize ⌄⌄⌄`\n```js\n init() {\n console.log(\"Exit Button init!\",this.client);\n this.createExitPanel();\n }\n```","src/content/docs/05_Exit_Button.md","8a1b55e67864fa9e",{"html":120,"metadata":121},"\u003Cp>When in the WebXR environment using a headset, I could not figure out how to leave the experience, so I made an Exit Demo Panel.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">ExitButton.js\u003C/code> file.\u003C/p>\n\u003Cp>Create the constructor for the Class:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create constructor ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">constructor\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">super\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Keep a reference to the panel so we can destroy it later\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">exitPanelText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Exit Demo\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" constructor() { super(); // Keep a reference to the panel so we can destroy it later this.panel = null; this.statusText = null; this.exitPanelText = "Exit Demo"; }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Function to create a panel for the Exit Button:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create Exit Button panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createExitPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// SAFETY: If a panel already exists, don't create another one.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Creating Exit Button...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Create the Panel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">SpatialPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">width: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">height: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#2b2b2baa\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2.0\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">rotation\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">Math\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">PI\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addGrid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Status Text\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">exitPanelText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ffffff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">.4\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Orbiter\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">orbiter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addOrbiter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">orbiter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addExitButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateLayouts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" createExitPanel() { // SAFETY: If a panel already exists, don't create another one. if (this.panel) return; console.log("Creating Exit Button..."); // 1. Create the Panel this.panel = new xb.SpatialPanel({ width: 0.5, height: 0.5, backgroundColor: '#2b2b2baa' }); this.panel.position.set( 0, xb.user.height, 2.0 ); this.panel.rotation.set(0, Math.PI, 0); this.add(this.panel); const grid = this.panel.addGrid(); // 2. Status Text this.statusText = grid.addRow({ weight: 1 }).addText({ text: this.exitPanelText, fontColor: '#ffffff', fontSize: .4, }); // Orbiter const orbiter = grid.addOrbiter(); orbiter.addExitButton(); this.panel.updateLayouts(); }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Initialize Class when loaded into the page:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Initialize ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">init\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Exit Button init!\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createExitPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" init() { console.log("Exit Button init!",this.client); this.createExitPanel(); }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":122,"localImagePaths":123,"remoteImagePaths":124,"frontmatter":125,"imagePaths":126},[],[],[],{"title":111,"description":112},[],"06_add_to_xr_blocks",{"id":127,"data":129,"body":135,"filePath":136,"digest":137,"rendered":138},{"title":130,"description":131,"editUrl":16,"head":132,"template":33,"sidebar":133,"pagefind":16,"draft":23},"Add panels to XR Blocks","adding panels to WebXR application",[],{"hidden":23,"attrs":134},{},"Let's add the 2 panels to the application.\n\nThe following code will be placed in the `main.js` file.\n\nFirst, import the Panels:\n`// ⌄⌄⌄ import Vonage Call Panel and Exit Button ⌄⌄⌄`\n```js\nimport { VonageAudioCall } from './VonageAudioCall.js';\nimport { ExitPanel } from './ExitButton.js';\n```\n\nCreate instances and add to the application:\n`// ⌄⌄⌄ add Vonage Call Panel and Exit Button ⌄⌄⌄`\n```js\nxb.add(new VonageAudioCall());\nxb.add(new ExitPanel());\n```\n\n## Time to test the application\nRefresh the application and try to call the phone number that was purchased and assigned while running the setup script.\n\n> Note: You can find the phone number connected to your Vonage application in the `.env` file.","src/content/docs/06_Add_To_XR_Blocks.md","d3b20f81f928d1fb",{"html":139,"metadata":140},"\u003Cp>Let’s add the 2 panels to the application.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">main.js\u003C/code> file.\u003C/p>\n\u003Cp>First, import the Panels:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ import Vonage Call Panel and Exit Button ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { VonageAudioCall } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./VonageAudioCall.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { ExitPanel } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./ExitButton.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { VonageAudioCall } from './VonageAudioCall.js';import { ExitPanel } from './ExitButton.js';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Create instances and add to the application:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ add Vonage Call Panel and Exit Button ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">VonageAudioCall\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">());\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">ExitPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">());\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"xb.add(new VonageAudioCall());xb.add(new ExitPanel());\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"time-to-test-the-application\">Time to test the application\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#time-to-test-the-application\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “Time to test the application”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Refresh the application and try to call the phone number that was purchased and assigned while running the setup script.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Note: You can find the phone number connected to your Vonage application in the \u003Ccode dir=\"auto\">.env\u003C/code> file.\u003C/p>\n\u003C/blockquote>",{"headings":141,"localImagePaths":145,"remoteImagePaths":146,"frontmatter":147,"imagePaths":148},[142],{"depth":82,"slug":143,"text":144},"time-to-test-the-application","Time to test the application",[],[],{"title":130,"description":131},[],"07_congrats",{"id":149,"data":151,"body":157,"filePath":158,"digest":159,"rendered":160},{"title":152,"description":153,"editUrl":16,"head":154,"template":33,"sidebar":155,"pagefind":16,"draft":23},"Congratulations!","What's next.",[],{"hidden":23,"attrs":156},{},"## You did it!\n\nYou now have a WebXR application using XR Blocks and the Vonage Voice API that can receive phone calls.\n\n## Export your application\n\nIf you'd like to save the application you created to your personal GitHub acoount, open a new Terminal window (press the + button) and run this command:\n\n```bash\nchmod +x export.sh && ./export.sh\n```\n\n## Create your own XR Blocks application with AI\n\nXR Blocks has a Google Gemini Gem, that allows you to create a WebXR application using just plain text. Want to create something? \u003Ca href=\"https://xrblocks.github.io/gem\" target=\"_blank\">Give it a try.\u003C/a>\n\n## What's Next?\n\n- Can you create a WebXR application that makes phone calls? How about a voice chat in a WebXR environment?\n- Learn more about the Vonage Voice API in our \u003Ca href=\"https://developer.vonage.com/en/voice/voice-api/overview\" target=\"_blank\">developer documenation\u003C/a>\n- Want to learn more about other Vonage products? Try our interactive \u003Ca href=\"https://developer.vonage.com/en/learning-center\" target=\"_blank\">Learning Center\u003C/a> and earn certificates.\n- Connect with us on \u003Ca href=\"https://x.com/vonagedev\" target=\"_blank\">Twitter / X\u003C/a>, \u003Ca href=\"https://bsky.app/profile/did:plc:btgbhfwrllglgvyuqrmi2sev\" target=\"_blank\">Bluesky\u003C/a> and \u003Ca href=\"https://www.linkedin.com/company/vonage-dev\" target=\"_blank\">LinkedIn\u003C/a>\n- Join our \u003Ca href=\"https://vonage.dev/slack\" target=\"_blank\">Developer Community Slack channel\u003C/a> to connect with others building with Vonage","src/content/docs/07_Congrats.md","53a92988967e5d1c",{"html":161,"metadata":162},"\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"you-did-it\">You did it!\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#you-did-it\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “You did it!”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>You now have a WebXR application using XR Blocks and the Vonage Voice API that can receive phone calls.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"export-your-application\">Export your application\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#export-your-application\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “Export your application”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>If you’d like to save the application you created to your personal GitHub acoount, open a new Terminal window (press the + button) and run this command:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chmod\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">+x\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">export.sh\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> && \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">./export.sh\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"chmod +x export.sh && ./export.sh\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"create-your-own-xr-blocks-application-with-ai\">Create your own XR Blocks application with AI\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#create-your-own-xr-blocks-application-with-ai\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “Create your own XR Blocks application with AI”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>XR Blocks has a Google Gemini Gem, that allows you to create a WebXR application using just plain text. Want to create something? \u003Ca href=\"https://xrblocks.github.io/gem\" target=\"_blank\">Give it a try.\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"whats-next\">What’s Next?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#whats-next\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “What’s Next?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Can you create a WebXR application that makes phone calls? How about a voice chat in a WebXR environment?\u003C/li>\n\u003Cli>Learn more about the Vonage Voice API in our \u003Ca href=\"https://developer.vonage.com/en/voice/voice-api/overview\" target=\"_blank\">developer documenation\u003C/a>\u003C/li>\n\u003Cli>Want to learn more about other Vonage products? Try our interactive \u003Ca href=\"https://developer.vonage.com/en/learning-center\" target=\"_blank\">Learning Center\u003C/a> and earn certificates.\u003C/li>\n\u003Cli>Connect with us on \u003Ca href=\"https://x.com/vonagedev\" target=\"_blank\">Twitter / X\u003C/a>, \u003Ca href=\"https://bsky.app/profile/did:plc:btgbhfwrllglgvyuqrmi2sev\" target=\"_blank\">Bluesky\u003C/a> and \u003Ca href=\"https://www.linkedin.com/company/vonage-dev\" target=\"_blank\">LinkedIn\u003C/a>\u003C/li>\n\u003Cli>Join our \u003Ca href=\"https://vonage.dev/slack\" target=\"_blank\">Developer Community Slack channel\u003C/a> to connect with others building with Vonage\u003C/li>\n\u003C/ul>",{"headings":163,"localImagePaths":176,"remoteImagePaths":177,"frontmatter":178,"imagePaths":179},[164,167,170,173],{"depth":82,"slug":165,"text":166},"you-did-it","You did it!",{"depth":82,"slug":168,"text":169},"export-your-application","Export your application",{"depth":82,"slug":171,"text":172},"create-your-own-xr-blocks-application-with-ai","Create your own XR Blocks application with AI",{"depth":82,"slug":174,"text":175},"whats-next","What’s Next?",[],[],{"title":152,"description":153},[]] \ No newline at end of file diff --git a/sources/webxr-javascript-workshop/.astro/settings.json b/sources/webxr-javascript-workshop/.astro/settings.json index 3f75c6b8..c41bdd24 100644 --- a/sources/webxr-javascript-workshop/.astro/settings.json +++ b/sources/webxr-javascript-workshop/.astro/settings.json @@ -1,5 +1,5 @@ { "_variables": { - "lastUpdateCheck": 1775761538082 + "lastUpdateCheck": 1784923264156 } } \ No newline at end of file diff --git a/sources/webxr-javascript-workshop/.vscode/extensions.json b/sources/webxr-javascript-workshop/.vscode/extensions.json new file mode 100644 index 00000000..de4e2f35 --- /dev/null +++ b/sources/webxr-javascript-workshop/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "astro-build.astro-vscode", + "ms-vscode.live-server" + ] +} \ No newline at end of file diff --git a/sources/webxr-javascript-workshop/.vscode/tasks.json b/sources/webxr-javascript-workshop/.vscode/tasks.json new file mode 100644 index 00000000..ee6b95ff --- /dev/null +++ b/sources/webxr-javascript-workshop/.vscode/tasks.json @@ -0,0 +1,21 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Tutorial Editor", + "type": "shell", + "command": "npm install && npm run dev", + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "runOptions": { + "runOn": "folderOpen" + } + } + ] +} \ No newline at end of file diff --git a/sources/webxr-javascript-workshop/project/export.sh b/sources/webxr-javascript-workshop/project/export.sh new file mode 100644 index 00000000..3b2e60fa --- /dev/null +++ b/sources/webxr-javascript-workshop/project/export.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Ensure execution stops if a step fails +set -e + +echo "=========================================" +echo " 📦 Exporting Your Workshop Project " +echo "=========================================" + +# 1. Initialize a clean, local repository +echo "Initializing a brand new git tree..." +git init -b main + +# 2. Stage and commit all target workshop files +echo "Staging files..." +git add . +git commit -m "Initial commit: Completed Vonage Voice API Workshop" + +# 3. Use GitHub CLI for an elegant, interactive push +echo "" +echo "Let's upload this to your personal GitHub profile." +echo "Follow the prompts below to authenticate and name your new repository." +echo "--------------------------------------------------" + +# 'gh repo create' natively prompts the user if they want to create a repo from the current folder, +# names it, sets visibility, creates it on GitHub, and adds/pushes the remote automatically! +gh repo create --source=. --remote=origin --push + +echo "" +echo "=========================================" +echo " 🎉 SUCCESS! Your project is safely on GitHub." +echo "=========================================" + \ No newline at end of file diff --git a/sources/webxr-javascript-workshop/project/pages/index.html b/sources/webxr-javascript-workshop/project/pages/index.html index eac188b2..94e4ed8c 100644 --- a/sources/webxr-javascript-workshop/project/pages/index.html +++ b/sources/webxr-javascript-workshop/project/pages/index.html @@ -1,4 +1,4 @@ - + XR Blocks with Call Answering @@ -27,7 +27,8 @@ "lit": "https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js", "lit/": "https://esm.run/lit@3/", "xrblocks": "https://cdn.jsdelivr.net/gh/google/xrblocks@build/xrblocks.js", - "xrblocks/addons/": "https://cdn.jsdelivr.net/gh/google/xrblocks@build/addons/" + "xrblocks/addons/": "https://cdn.jsdelivr.net/gh/google/xrblocks@build/addons/", + "lipsync": "https://cdn.jsdelivr.net/gh/google/xrblocks@build/addons/lipsync/index.js" } } @@ -40,4 +41,4 @@ > - \ No newline at end of file + diff --git a/sources/webxr-javascript-workshop/project/static/VonageAudioCall.js b/sources/webxr-javascript-workshop/project/static/VonageAudioCall.js index c044fdcd..2b0156b6 100644 --- a/sources/webxr-javascript-workshop/project/static/VonageAudioCall.js +++ b/sources/webxr-javascript-workshop/project/static/VonageAudioCall.js @@ -1,25 +1,44 @@ +import * as THREE from 'three'; import * as xb from 'xrblocks'; +import { LipsyncMouth } from 'lipsync'; +import { Keyboard } from 'xrblocks/addons/virtualkeyboard/Keyboard.js'; -export class VonageAudioCall extends xb.Script { +// ⌄⌄⌄ Set Quick Replies ⌄⌄⌄ +export class VonageAudioCall extends xb.Script { // ⌄⌄⌄ Create constructor ⌄⌄⌄ - - // ⌄⌄⌄ Create call panel ⌄⌄⌄ - - // ⌄⌄⌄ Update call controls ⌄⌄⌄ - - // ⌄⌄⌄ Remove call panel ⌄⌄⌄ - - // ⌄⌄⌄ Answer call method ⌄⌄⌄ - - // ⌄⌄⌄ Reject call method ⌄⌄⌄ - - // ⌄⌄⌄ Hang Up call method ⌄⌄⌄ - - // ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄ - - // ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ - - // ⌄⌄⌄ Initialize ⌄⌄⌄ - -} \ No newline at end of file + // ⌄⌄⌄ Create 3D Avatar ⌄⌄⌄ + // ⌄⌄⌄ Remove 3D Avatar ⌄⌄⌄ + // ⌄⌄⌄ Create Call panel ⌄⌄⌄ + // ⌄⌄⌄ Update Call controls ⌄⌄⌄ + // ⌄⌄⌄ Remove Call panel ⌄⌄⌄ + // ⌄⌄⌄ Show Virtual Keyboard ⌄⌄⌄ + // ⌄⌄⌄ Hide Virtual Keyboard ⌄⌄⌄ + // ⌄⌄⌄ Toggle Virtual Keyboard ⌄⌄⌄ + // ⌄⌄⌄ Send Quick Reply ⌄⌄⌄ + // ⌄⌄⌄ Send Custom Text ⌄⌄⌄ + // ⌄⌄⌄ Create Reply panel ⌄⌄⌄ + // ⌄⌄⌄ Remove Reply panel ⌄⌄⌄ + // ⌄⌄⌄ Answer call method ⌄⌄⌄ + // ⌄⌄⌄ Reject call method ⌄⌄⌄ + // ⌄⌄⌄ Hang Up call method ⌄⌄⌄ + // ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄ + // ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ + // ⌄⌄⌄ Initialize ⌄⌄⌄ + + // the update() method runs per frame. This allows the 3D Avatar to face the user as they move around + update() { + const head = this.puppetHead; + const cam = xb.core?.camera; + if (!head || !cam) return; + + cam.getWorldPosition(this._camWorld); + head.getWorldPosition(this._headWorld); + + // Mirror the camera through the head centre so local -Z faces the user + const targetX = 2 * this._headWorld.x - this._camWorld.x; + const targetZ = 2 * this._headWorld.z - this._camWorld.z; + // Clamp Y so the avatar only yaws — it won't pitch if you're taller/shorter + head.lookAt(targetX, this._headWorld.y, targetZ); + } +} diff --git a/sources/webxr-javascript-workshop/setup-project.js b/sources/webxr-javascript-workshop/setup-project.js index 2bae34e0..a42cea80 100644 --- a/sources/webxr-javascript-workshop/setup-project.js +++ b/sources/webxr-javascript-workshop/setup-project.js @@ -1,6 +1,7 @@ require('dotenv').config(); const fs = require('fs'); +const path = require('path'); const { Vonage } = require('@vonage/server-sdk'); @@ -12,24 +13,29 @@ console.log('setup.js running...'); if (process.env.VONAGE_API_KEY && process.env.VONAGE_API_SECRET) { // If the environment variables are already set, use them console.log('Environment variables already set. Skipping setup.'); - process.exit(); + process.exit(); } - + let step = 'SET_API_KEY'; console.log('Vonage setup utility for Github Codespaces -- press "q" to exit'); -console.log('This utility will need your Vonage API key and API secret. They will be saved to your .env file,'); -console.log('where they will be visible only to you and collaborators on this project.'); -console.log('Find your API key and secret at: https://dashboard.vonage.com/getting-started-guide'); +console.log( + 'This utility will need your Vonage API key and API secret. They will be saved to your .env file,' +); +console.log( + 'where they will be visible only to you and collaborators on this project.' +); +console.log( + 'Find your API key and secret at: https://dashboard.vonage.com/getting-started-guide' +); console.log('process.env.CODESPACE_NAME: ', process.env.CODESPACE_NAME); console.log('Enter your API Key:'); let input = process.stdin; -input.on('data', data => { - +input.on('data', (data) => { if (data.toString().trim() === 'q') { - // exit + // exit return process.exit(); } - + switch (step) { case 'SET_API_KEY': return setApiKey(data); @@ -51,12 +57,13 @@ input.on('data', data => { break; default: } - - }); function setApiKey(data) { - if (data.toString().replace(/\n/g, '').length === 0 || data.toString().replace(/\n/g, '') === ' ') { + if ( + data.toString().replace(/\n/g, '').length === 0 || + data.toString().replace(/\n/g, '') === ' ' + ) { console.log('(Can not be blank.) Enter you API key:'); } else { process.env.VONAGE_API_KEY = data.toString().replace(/\n/g, ''); @@ -67,7 +74,10 @@ function setApiKey(data) { } function setApiSecret(data) { - if (data.toString().replace(/\n/g, '').length === 0 || data.toString().replace(/\n/g, '') === ' ') { + if ( + data.toString().replace(/\n/g, '').length === 0 || + data.toString().replace(/\n/g, '') === ' ' + ) { console.log('(Can not be blank.) Enter you API secret:'); } else { process.env.VONAGE_API_SECRET = data.toString().replace(/\n/g, ''); @@ -78,73 +88,86 @@ function setApiSecret(data) { } function setAppName(data) { - if (data.toString().replace(/\n/g, '').length === 0 || data.toString().replace(/\n/g, '') === ' ') { + if ( + data.toString().replace(/\n/g, '').length === 0 || + data.toString().replace(/\n/g, '') === ' ' + ) { console.log('(Can not be blank.) Enter a name for your Application:'); } else { - createApp(data); - + createApp(data); } return true; } function buyNumberQuestion(data) { // console.log("data:", data); - if (data.toString().replace(/\n/g, '').length === 0 || data.toString().replace(/\n/g, '') === ' ') { + if ( + data.toString().replace(/\n/g, '').length === 0 || + data.toString().replace(/\n/g, '') === ' ' + ) { console.log('(Can not be blank.) Want to Buy a number? (Y/N):'); - } else if (data.toString().replace(/\n/g, '').toLowerCase() === 'y'){ - + } else if (data.toString().replace(/\n/g, '').toLowerCase() === 'y') { // process.env.VONAGE_API_SECRET = data.toString().replace(/\n/g, ''); step = 'SET_COUNTRY_CODE'; - console.log('Set the country code for your number (ex. US or GB):'); + console.log('Set the country code for your number (ex. US or GB):'); } else if (data.toString().replace(/\n/g, '').toLowerCase() === 'n') { // answered No to question - writeEnv(); + writeEnv(); } return true; } function setCountryCode(data) { - if (data.toString().replace(/\n/g, '').length === 0 || data.toString().replace(/\n/g, '') === ' ') { - console.log('(Can not be blank.) Set the country code for your number (ex. US or GB):'); + if ( + data.toString().replace(/\n/g, '').length === 0 || + data.toString().replace(/\n/g, '') === ' ' + ) { + console.log( + '(Can not be blank.) Set the country code for your number (ex. US or GB):' + ); } else { - buyPhoneNumber(data) + buyPhoneNumber(data); } return true; } -function buyPhoneNumber(data){ +function buyPhoneNumber(data) { const countryCode = data.toString().replace(/\n/g, ''); process.env.COUNTRY_CODE = data.toString().replace(/\n/g, '').toUpperCase(); //Search for a number console.log('Searching for a number in country: ', countryCode); - vonage.numbers.getAvailableNumbers({ + vonage.numbers + .getAvailableNumbers({ country: process.env.COUNTRY_CODE, features: ['VOICE', 'SMS'], - }) - .then((results) => { - const numbers = results.numbers; - console.log('Found numbers: ', numbers); - // Purchase a number - if (numbers.length === 0) { - console.log('No numbers found in this country. Please try another country code.'); - return; - } - console.log('Found a number: ', numbers[0].msisdn); - vonage.numbers.buyNumber({ - country: numbers[0].country, - msisdn: numbers[0].msisdn, }) - .then((result) => { - console.log('Bought the number!'); - updatePhoneNumber(numbers[0]); + .then((results) => { + const numbers = results.numbers; + console.log('Found numbers: ', numbers); + // Purchase a number + if (numbers.length === 0) { + console.log( + 'No numbers found in this country. Please try another country code.' + ); + return; + } + console.log('Found a number: ', numbers[0].msisdn); + vonage.numbers + .buyNumber({ + country: numbers[0].country, + msisdn: numbers[0].msisdn, + }) + .then((result) => { + console.log('Bought the number!'); + updatePhoneNumber(numbers[0]); + }) + .catch((error) => { + console.error('Error buying number:', error); + }); }) .catch((error) => { - console.error("Error buying number:", error); + console.error(error); }); - }) - .catch((error) => { - console.error(error) - }); } async function updatePhoneNumber(number) { @@ -161,56 +184,62 @@ async function updatePhoneNumber(number) { } else { console.log('Added number to application!'); process.env.VONAGE_PHONE_NUMBER = number.msisdn; - writeEnv(); + // writeEnv(); + sanitizeWorkshopEnvironment(); } } function createApp(data) { console.log('Creating your Application...'); - vonage = new Vonage({ - apiKey: process.env.VONAGE_API_KEY, - apiSecret: process.env.VONAGE_API_SECRET - }, { - debug: false - }); + vonage = new Vonage( + { + apiKey: process.env.VONAGE_API_KEY, + apiSecret: process.env.VONAGE_API_SECRET, + }, + { + debug: false, + } + ); - vonage.applications.createApplication({ + vonage.applications + .createApplication({ name: data.toString().replace(/\n/g, ''), capabilities: { - voice: { - webhooks: { - answer_url: { - address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/voice/answer`, - http_method: "GET" - }, - event_url: { - address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/voice/event`, - http_method: "POST" - } - } + voice: { + webhooks: { + answer_url: { + address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/voice/answer`, + http_method: 'GET', + }, + event_url: { + address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/voice/event`, + http_method: 'POST', + }, }, - messages: { - webhooks: { - inbound_url: { - address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/webhooks/inbound`, - http_method: "POST" - }, - status_url: { - address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/webhooks/status`, - http_method: "POST" - } - } + }, + messages: { + webhooks: { + inbound_url: { + address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/webhooks/inbound`, + http_method: 'POST', + }, + status_url: { + address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/webhooks/status`, + http_method: 'POST', + }, }, - rtc: { - webhooks: { - event_url: { - address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/webhooks/rtcevent`, - http_method: "POST" - } - } - } - } - }).then((app) => { + }, + rtc: { + webhooks: { + event_url: { + address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/webhooks/rtcevent`, + http_method: 'POST', + }, + }, + }, + }, + }) + .then((app) => { console.log('Application created with ID: ', app.id); process.env.API_APPLICATION_ID = app.id; fs.writeFile(__dirname + '/private.key', app.keys.private_key, (err) => { @@ -226,22 +255,22 @@ function createApp(data) { process.env.PRIVATE_KEY64 = base64PrivateKey; //Search and Buy phone number - process.env.VONAGE_APPLICATION_NAME = data.toString().replace(/\n/g, ''); + process.env.VONAGE_APPLICATION_NAME = data + .toString() + .replace(/\n/g, ''); step = 'BUY_NUMBER'; console.log('Want to Buy a number? (Y/N):'); - } catch (error) { console.error('An error occurred:', error); } - - } }); - }).catch((error) => { + }) + .catch((error) => { console.error('Error creating Application: ', error); process.exit(); - }); - return true; + }); + return true; } function writeEnv() { @@ -254,36 +283,74 @@ API_APPLICATION_ID="${process.env.API_APPLICATION_ID}" COUNTRY_CODE="${process.env.COUNTRY_CODE}" VONAGE_PHONE_NUMBER="${process.env.VONAGE_PHONE_NUMBER}" PRIVATE_KEY64="${process.env.PRIVATE_KEY64}"`; - + fs.writeFile(__dirname + '/.env', contents, (err) => { if (err) { - console.log('Error writing .env file: ',err); + console.log('Error writing .env file: ', err); } else { console.log('Environment variables saved to .env'); process.exit(); } }); - } function createUser() { - //create user - const vonage = new Vonage({ - apiKey: process.env.VONAGE_API_KEY, - apiSecret: process.env.VONAGE_API_SECRET, - applicationId: process.env.API_APPLICATION_ID, - privateKey: __dirname + process.env.PRIVATE_KEY - }, {debug: false}); - vonage.users.create({ + //create user + const vonage = new Vonage( + { + apiKey: process.env.VONAGE_API_KEY, + apiSecret: process.env.VONAGE_API_SECRET, + applicationId: process.env.API_APPLICATION_ID, + privateKey: __dirname + process.env.PRIVATE_KEY, + }, + { debug: false } + ); + vonage.users.create( + { name: process.env.ADMIN_NAME, - display_name: process.env.ADMIN_NAME - },(err, response) => { + display_name: process.env.ADMIN_NAME, + }, + (err, response) => { if (err) { - console.log('Error creating user: ',err); + console.log('Error creating user: ', err); } else { console.log('User created. ID: ', response.id); process.exit(); } - }); + } + ); +} + +// Allow coding exercise to be exported to user's GitHub account +function sanitizeWorkshopEnvironment() { + // Look for the parent git directory (one level up from the 'project' CWD) + const parentGitPath = path.join(__dirname, '../.git'); + const projectGitPath = path.join(__dirname, '.git'); + + try { + // 1. Remove any accidentally created git tracker inside the project folder + if (fs.existsSync(projectGitPath)) { + fs.rmSync(projectGitPath, { recursive: true, force: true }); + console.log('Cleared local .git directory to ensure a clean slate.'); + } -} \ No newline at end of file + // 2. Sever the tie with your main multi-workshop repository + if (fs.existsSync(parentGitPath)) { + // Renaming it prevents Git from looking upwards for tracking configurations, + // while preserving your workshop configuration integrity. + const backupPath = path.join(__dirname, '../.git_bak'); + if (!fs.existsSync(backupPath)) { + fs.renameSync(parentGitPath, backupPath); + console.log( + 'Successfully separated current workspace from the main repository tracking.' + ); + } + } + process.exit(); + } catch (error) { + console.error( + 'Warning: Failed to safely disconnect parent repository framework:', + error.message + ); + } +} diff --git a/sources/webxr-javascript-workshop/src/content/docs/04_Vonage_Call_Panel.md b/sources/webxr-javascript-workshop/src/content/docs/04_Vonage_Call_Panel.md index 2eda61a1..b32e40c8 100644 --- a/sources/webxr-javascript-workshop/src/content/docs/04_Vonage_Call_Panel.md +++ b/sources/webxr-javascript-workshop/src/content/docs/04_Vonage_Call_Panel.md @@ -3,12 +3,33 @@ title: Vonage Call Panel description: Create XR Blocks UI to answer phone calls --- -We'll be creating the UI to recieve phone calls via the Vonage Voice API using the XR Blocks library's SpatialPanel Class. +Now, we'll be creating the UI. + +To recieve phone calls via the Vonage Voice API using the XR Blocks library's SpatialPanel Class. + +To show the 3D Avatar for the caller, we will use the Lipsync (Addon). + +The Vonage Voice Client SDK's Text to Speech will be used to send the quick replies and typed messages into the call. + +The virtual keyboard that allows us to type those messages will come from the Virtual Keyboard (Addon). The following code will be placed in the `VonageAudioCall.js` file. -First, let's initiate the constructor for our panel with some variables: +First, we will set the Quick Replies that the user can send into the call. +Find `// ⌄⌄⌄ Set Quick Replies ⌄⌄⌄` and add this code: + +```js +const QUICK_REPLIES = [ + { label: "Meeting", message: "In a meeting, I'll call you back." }, + { label: "Talk Later", message: "Can't talk right now. I'll talk later." }, + { label: "OMW!", message: "On my way! Talk soon." }, + { label: "5 Mins", message: "Call you back in 5 minutes." }, +]; +``` + +Let's initiate the constructor for our panel with some variables: `// ⌄⌄⌄ Create constructor ⌄⌄⌄` + ```js constructor() { super(); @@ -16,23 +37,96 @@ constructor() { this.client = new vonageClientSDK.VonageClient(); this.callId = null; // Keep a reference to the panel so we can destroy it later - this.panel = null; + this.panel = null; this.statusText = null; this.userName = "XR_User_1"; this.grid = null; this.controlRow = null; + this.puppetHead = null; + this.face = null; + this.mouth = null; + this._camWorld = new THREE.Vector3(); + this._headWorld = new THREE.Vector3(); + this.replyPanel = null; + this.typedTextView = null; + this._currentTypedText = ''; + this.keyboard = null; +} +``` + +Here's the function to create an Avatar and add the MediaStream for the LipSync feature: `// ⌄⌄⌄ Create 3D Avatar ⌄⌄⌄` + +```js +_createAvatar(stream) { + // Safety: don't create a second avatar if one already exists + if (this.puppetHead) return; + + console.log("Creating lipsync avatar..."); + + const faceR = 0.1; + + const head = new THREE.Group(); + // Position: in front of the user, roughly at face height + head.position.set(0, xb.user.height, -1.2); + + // --- Sphere face mesh --- + const faceGeom = new THREE.SphereGeometry(faceR, 32, 24); + const faceMat = new THREE.MeshStandardMaterial({ + color: 0xf2d4b3, + roughness: 0.6, + metalness: 0.05, + }); + const faceMesh = new THREE.Mesh(faceGeom, faceMat); + head.add(faceMesh); + + this.face = new xb.StylizedFace({ showEyes: true }); + head.add(this.face); + + this.mouth = new LipsyncMouth(stream, { target: this.face }); + head.add(this.mouth); + + this.puppetHead = head; + this.add(head); +} +``` + +This function will remove the 3D Avatar when the call is over: +`// ⌄⌄⌄ Remove 3D Avatar ⌄⌄⌄` + +```js +_removeAvatar() { + if (!this.puppetHead) return; + + console.log("Removing lipsync avatar..."); + + if (this.mouth) { + // Detach from the head group before nulling the reference + this.mouth.parent?.remove(this.mouth); + this.mouth = null; + } + + if (this.face) { + this.face.parent?.remove(this.face); + // dispose() frees the underlying canvas/texture to avoid memory leaks + this.face.dispose(); + this.face = null; + } + + this.remove(this.puppetHead); + this.puppetHead = null; } ``` Here's the function to create the panel: -`// ⌄⌄⌄ Create call panel ⌄⌄⌄` +`// ⌄⌄⌄ Create Call panel ⌄⌄⌄` + ```js -createCallPanel(callerName) { +_createCallPanel(callerName) { // SAFETY: If a panel already exists, don't create another one. if (this.panel) return; console.log("Creating Call UI..."); - + // 1. Create the Panel this.panel = new xb.SpatialPanel({ backgroundColor: '#2b2b2baa' }); this.panel.position.set( @@ -57,7 +151,8 @@ createCallPanel(callerName) { ``` Function to update the call control section: -`// ⌄⌄⌄ Update call controls ⌄⌄⌄` +`// ⌄⌄⌄ Update Call controls ⌄⌄⌄` + ```js updateControlRow(state) { if (!this.grid) return; @@ -107,9 +202,10 @@ updateControlRow(state) { ``` This function will remove the panel once the call is over: -`// ⌄⌄⌄ Remove call panel ⌄⌄⌄` +`// ⌄⌄⌄ Remove Call panel ⌄⌄⌄` + ```js -removeCallPanel() { +_removeCallPanel() { if (this.panel) { console.log("Destroying Call UI..."); this.remove(this.panel); @@ -118,62 +214,287 @@ removeCallPanel() { this.statusText = null; this.controlRow = null; } + this._removeReplyPanel(); +} +``` + +Now, let's add the Virtual Keyboard that will allow us to send text messages that will be spoken into the call. + +Here's the code to show the Keyboard: +`// ⌄⌄⌄ Show Virtual Keyboard ⌄⌄⌄` + +```js +_showKeyboard() { + if (this.keyboard) return; + + this.keyboard = new Keyboard(); + // Position it below and aligned with the reply panel + this.keyboard.position.set( + 0, + xb.user.height - 1.35, + -xb.user.objectDistance + 1 + ); + this.add(this.keyboard); + + // Update the display on every keystroke + this.keyboard.onTextChanged = (text) => { + this._currentTypedText = text; + if (this.typedTextView) { + this.typedTextView.text = text.length > 0 ? text : 'Tap to type...'; + } + }; + + // Enter key sends immediately — same as tapping the Send button + this.keyboard.onEnterPressed = (text) => { + this._sendTypedText(); + }; +} +``` + +If we want to hide the Keyboard, here's the code: +`// ⌄⌄⌄ Hide Virtual Keyboard ⌄⌄⌄` + +```js +_hideKeyboard() { + if (!this.keyboard) return; + this.remove(this.keyboard); + this.keyboard = null; +} +``` + +To toggle between showing and hidding the keyboard, we have this code: +`// ⌄⌄⌄ Toggle Virtual Keyboard ⌄⌄⌄` + +```js +_toggleKeyboard() { + this.keyboard ? this._hideKeyboard() : this._showKeyboard(); +} +``` + +Let's create the functions that will send the text to be said into the call just in case we can't talk at that moment. + +To send the Quick Replies that we set before: +`// ⌄⌄⌄ Send Quick Reply ⌄⌄⌄` + +```js +_sendQuickReply(message) { + if (!this.callId) return; + console.log(`Sending quick reply: "${message}"`); + + // Give the user immediate visual feedback in the status bar + if (this.statusText) this.statusText.text = 'Sending...'; + + this.client.say(this.callId, message) + .then(() => { + console.log('Quick reply sent successfully.'); + if (this.statusText) this.statusText.text = `Sent: "${message}"`; + }) + .catch(err => { + console.error('say() error:', err); + if (this.statusText) this.statusText.text = 'Failed to send message.'; + }); +} +``` + +In the case we want to carry on the conversation but maybe can't speak (ie in a public space), we can send custom text: +`// ⌄⌄⌄ Send Custom Text ⌄⌄⌄` + +```js +_sendTypedText() { + const text = this._currentTypedText.trim(); + if (!text) return; + if (!this.callId) return; + + console.log(`Sending typed text: "${text}"`); + if (this.statusText) this.statusText.text = 'Sending...'; + + this.client.say(this.callId, text) + .then(() => { + console.log('Typed text sent successfully.'); + if (this.statusText) this.statusText.text = `Sent: "${text}"`; + + // Clear the keyboard buffer and reset the display + if (this.keyboard) this.keyboard.setText(''); + this._currentTypedText = ''; + if (this.typedTextView) this.typedTextView.text = 'Tap to type...'; + }) + .catch(err => { + console.error('say() error:', err); + if (this.statusText) this.statusText.text = 'Failed to send message.'; + }); +} +``` + +Here we will create the Reply panel that will hold all the way we can send a text message into the call: +`// ⌄⌄⌄ Create Reply panel ⌄⌄⌄` + +```js +_createReplyPanel() { + if (this.replyPanel) return; + + this.replyPanel = new xb.SpatialPanel({ + backgroundColor: '#1a1a2ecc', + width: .75, + height: 0.9, + }); + // Offset to the right so it sits beside the main call panel + this.replyPanel.position.set( + 0.8, + xb.user.height - 0.5, + -xb.user.objectDistance + ); + this.add(this.replyPanel); + + const grid = this.replyPanel.addGrid(); + + grid.addRow({ weight: 0.06 }).addText({ + text: 'Quick Replies', + fontColor: '#9b9bff', + fontSize: 0.055, + }); + + const pairs = [ + QUICK_REPLIES.slice(0, 2), // [ Meeting, Talk Later ] + QUICK_REPLIES.slice(2, 4), // [ OMW!, 5 Mins ] + ]; + + pairs.forEach(pair => { + const row = grid.addRow({ weight: 0.20 }); + pair.forEach(({ label, message }) => { + const btn = row.addCol({ weight: 0.5 }).addTextButton({ + text: label, + fontSize: 0.35, + backgroundColor: '#2e2e50', + fontColor: '#ffffff', + }); + btn.onTriggered = () => this._sendQuickReply(message); + }); + }); + + grid.addRow({ weight: 0.06 }).addText({ + text: 'Talk via Text', + fontColor: '#9b9bff', + fontSize: 0.055, + }); + + this.typedTextView = grid.addRow({ weight: 0.18 }).addText({ + text: 'Tap to type...', + fontColor: '#ffffff', + fontSize: 0.065, + textAlign: 'left', + }); + + const actionRow = grid.addRow({ weight: 0.30 }); + + const kbBtn = actionRow.addCol({ weight: 0.5 }).addIconButton({ + text: 'keyboard', + fontSize: 0.5, + backgroundColor: '#2e3a4a', + }); + kbBtn.onTriggered = () => this._toggleKeyboard(); + + const sendBtn = actionRow.addCol({ weight: 0.5 }).addIconButton({ + text: 'send', + fontSize: 0.5, + backgroundColor: '#1a4a2a', + }); + sendBtn.onTriggered = () => this._sendTypedText(); + + this.replyPanel.updateLayouts(); +} +``` + +Just like with the Call panel, we will have a function to remove the Reply panel: +`// ⌄⌄⌄ Remove Reply panel ⌄⌄⌄` + +```js +_removeReplyPanel() { + this._hideKeyboard(); + if (this.replyPanel) { + this.remove(this.replyPanel); + this.replyPanel = null; + this.typedTextView = null; + } + this._currentTypedText = ''; } ``` This function answers the call and updates the status and call control section: `// ⌄⌄⌄ Answer call method ⌄⌄⌄` + ```js _onAnswer() { console.log('Answering...'); this.client.answer(this.callId) - .then(() => { - console.log("Success answering call."); - this.statusText.text = `Call answered.`; - this.updateControlRow('CONNECTED'); - }) - .catch(error => { - console.error("Error answering call: ", error); - }); + .then(() => { + console.log("Success answering call."); + this.statusText.text = `Call answered.`; + this.updateControlRow('CONNECTED'); + + // ⌄⌄⌄ Show reply panel alongside the call panel ⌄⌄⌄ + this._createReplyPanel(); + + // get media stream + const audioElement = this.client.getAudioOutputElement(); + if (audioElement && audioElement.srcObject) { + // This is the active WebRTC MediaStream managed by Vonage + const remoteStream = audioElement.srcObject; + console.log('remoteStream: ', remoteStream); + + // Example: Grab individual audio tracks from the stream + const audioTracks = remoteStream.getAudioTracks(); + console.log("Active Audio Tracks:", audioTracks); + + // ⌄⌄⌄ Spin up the lipsync avatar driven by the remote stream ⌄⌄⌄ + this._createAvatar(remoteStream); + } + }) + .catch(error => { + console.error("Error answering call: ", error); + }); } ``` This function will reject the incoming call and remove the panel: `// ⌄⌄⌄ Reject call method ⌄⌄⌄` + ```js _onReject() { console.log('Rejecting...'); this.client.reject(this.callId) - .then(() => { - console.log("Success rejecting call."); - }) - .catch(error => { - console.error("Error rejecting call: ", error); - }); - // We manually destroy the panel here too, just in case the event lags - this.removeCallPanel(); + .then(() => { + console.log("Success rejecting call."); + }) + .catch(error => { + console.error("Error rejecting call: ", error); + }); + this._removeCallPanel(); + this._removeAvatar(); } ``` This function will hang up the ongoing call and remove the panel: `// ⌄⌄⌄ Hang Up call method ⌄⌄⌄ ` + ```js _onHangup() { console.log('Hanging up...'); this.client.hangup(this.callId) - .then(() => { - console.log("Success hanging up call."); - }) - .catch(error => { - console.error("Error hanging up call: ", error); - }); + .then(() => { + console.log("Success hanging up call."); + }) + .catch(error => { + console.error("Error hanging up call: ", error); + }); // We manually destroy the panel here too, just in case the event lags - this.removeCallPanel(); + this._removeCallPanel(); + this._removeAvatar(); } ``` Set up some listeners for the events that the Vonage Client SDK will emit and what to do: `// ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄` + ```js setupVonageListeners() { // --- CREATE UI ON INVITE --- @@ -181,9 +502,9 @@ setupVonageListeners() { this.callId = callId; const maskedNumber = from.replace(/\d(?=(?:\D*\d){4})/g, "*") console.log(`Incoming call from ${maskedNumber}`); - + // Trigger the UI creation here - this.createCallPanel(maskedNumber); + this._createCallPanel(maskedNumber); }); this.client.on('legStatusUpdate', (callId, legId, status) => { @@ -197,19 +518,22 @@ setupVonageListeners() { this.client.on('callInviteCancel', (callId) => { console.log(`Call cancelled: ${callId}`); this.callId = null; - this.removeCallPanel(); + this._removeCallPanel(); + this._removeAvatar(); }); this.client.on("callHangup", (callId, callQuality, reason) => { console.log(`Call hung up: ${reason}`); this.callId = null; - this.removeCallPanel(); + this._removeCallPanel(); + this._removeAvatar(); }); } ``` Get a token from the server so you can connect to a session: `// ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ ` + ```js async connectToVonage(name) { try { @@ -217,7 +541,7 @@ async connectToVonage(name) { // 1. Fetch the token (AWAIT the result) const response = await fetch(`/token?name=${name}`); - + if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } @@ -228,7 +552,7 @@ async connectToVonage(name) { // 2. Create the Session (AWAIT the result) const sessionId = await this.client.createSession(this.token); - + console.log("Session created successfully. Session ID:", sessionId); // 3. Update UI @@ -246,6 +570,7 @@ async connectToVonage(name) { Initialize the Class when loaded into the page: `// ⌄⌄⌄ Initialize ⌄⌄⌄` + ```js init() { console.log("Vonage init!",this.client); diff --git a/sources/webxr-javascript-workshop/src/content/docs/07_Congrats.md b/sources/webxr-javascript-workshop/src/content/docs/07_Congrats.md index 4f04c053..3687cd40 100644 --- a/sources/webxr-javascript-workshop/src/content/docs/07_Congrats.md +++ b/sources/webxr-javascript-workshop/src/content/docs/07_Congrats.md @@ -7,8 +7,22 @@ description: What's next. You now have a WebXR application using XR Blocks and the Vonage Voice API that can receive phone calls. +## Export your application + +If you'd like to save the application you created to your personal GitHub acoount, open a new Terminal window (press the + button) and run this command: + +```bash +chmod +x export.sh && ./export.sh +``` + +## Create your own XR Blocks application with AI + +XR Blocks has a Google Gemini Gem, that allows you to create a WebXR application using just plain text. Want to create something? Give it a try. + ## What's Next? + - Can you create a WebXR application that makes phone calls? How about a voice chat in a WebXR environment? - Learn more about the Vonage Voice API in our developer documenation -- Connect with us on Twitter / X and LinkedIn -- Join our Developer Community Slack channel to connect with others building with Vonage \ No newline at end of file +- Want to learn more about other Vonage products? Try our interactive Learning Center and earn certificates. +- Connect with us on Twitter / X, Bluesky and LinkedIn +- Join our Developer Community Slack channel to connect with others building with Vonage diff --git a/sources/webxr-javascript-workshop/src/content/docs/index.mdx b/sources/webxr-javascript-workshop/src/content/docs/index.mdx index 91830be9..174791d7 100644 --- a/sources/webxr-javascript-workshop/src/content/docs/index.mdx +++ b/sources/webxr-javascript-workshop/src/content/docs/index.mdx @@ -1,7 +1,7 @@ --- -title: Vonage Voice API Workshop +title: CreateHer Fest description: Let's build some sample applications! template: splash hero: - tagline: Let's build some sample applications! + tagline: DIALED IN! Answer calls in WebXR. --- diff --git a/sources/webxr-javascript-workshop/tutorial-config.json b/sources/webxr-javascript-workshop/tutorial-config.json index 84ff5f9f..bff8f65c 100644 --- a/sources/webxr-javascript-workshop/tutorial-config.json +++ b/sources/webxr-javascript-workshop/tutorial-config.json @@ -22,5 +22,8 @@ "project/static/ExitButton.js" ], "capabilities": [], - "version": "0.0.3" + "version": "0.0.4", + "customInstallCmd": "", + "customSetupCmd": "", + "filename": "webxr-javascript-workshop" } \ No newline at end of file diff --git a/sources/webxr-javascript-workshop/vonage-toolbar/app.ts b/sources/webxr-javascript-workshop/vonage-toolbar/app.ts index 6e057994..9861ba96 100644 --- a/sources/webxr-javascript-workshop/vonage-toolbar/app.ts +++ b/sources/webxr-javascript-workshop/vonage-toolbar/app.ts @@ -8,6 +8,10 @@ let tutorial: { starterFiles: string[]; capabilities: string[]; version: string; + filename: string; + customInstallCmd: string; + customSetupCmd: string; + customStartCmd: string; } = { files: [], openFiles: [], @@ -16,12 +20,17 @@ let tutorial: { starterFiles: [], capabilities: [], version: '', + filename: '', + customInstallCmd: '', + customSetupCmd: '', + customStartCmd: '' }; export default defineToolbarApp({ init(canvas, app, server) { const myWindow = document.createElement('astro-dev-toolbar-window'); const myContent = document.createElement('div'); + myContent.style.overflowY = 'auto'; myContent.innerHTML = `
Step 1: Select panels needed @@ -39,8 +48,14 @@ export default defineToolbarApp({
Step 2: Load an external repo (optional) - The repo will be loaded in the project folder. If there are any setup scripts needed to run the repo, please put them in the setup-project.js file. + The repo will be loaded in the project folder. +

Default install command is npm install, if you have custom install command, please enter it here: + +

Default setup command is node setup-project.js that will run the code in the setup-project.js file. If you have a custom setup command, please enter it here and make sure to create any files you need: + + +

Default start command is npm start, if you have custom start command, please enter it here:
Step 3: Set Starter Files to be used @@ -60,7 +75,7 @@ export default defineToolbarApp({
Step 5: Create steps - In the src -> content -> docs folder, please add the steps for the tutorial and delete reference.mdoc when finished. + In the src -> content -> docs folder, please add the steps for the tutorial. If you are using any components from the Reference page, please rename the file type from '.md' to '.mdoc' Delete reference.mdoc when finished.

See Reference for components you can add.

@@ -86,7 +101,12 @@ export default defineToolbarApp({
- Step 9: Finish up + Step 9: Enter filename for the zip file + This will be used also for the repo's folder name +
+
+
+ Step 10: Finish up Click to start generating the tutorial:

@@ -102,13 +122,22 @@ export default defineToolbarApp({ const astroToolbarWindow = canvas.querySelector('astro-dev-toolbar-window'); + const filenameInput = astroToolbarWindow?.querySelector( + '#filename' + ) as HTMLInputElement; + filenameInput.value = tutorial.filename !== '' ? tutorial.filename : ''; + filenameInput?.addEventListener('change', (event) => { + tutorial.filename = filenameInput?.value; + saveConfig(); + }); + const versionInput = astroToolbarWindow?.querySelector( '#version' ) as HTMLInputElement; versionInput.value = tutorial.version !== '' ? tutorial.version : ''; versionInput?.addEventListener('change', (event) => { tutorial.version = versionInput?.value; - saveTutorial(); + saveConfig(); }); const repositoryInput = astroToolbarWindow?.querySelector( @@ -118,45 +147,49 @@ export default defineToolbarApp({ tutorial.repository !== '' ? tutorial.repository : ''; repositoryInput?.addEventListener('change', (event) => { tutorial.repository = repositoryInput?.value; - saveTutorial(); + saveConfig(); }); - // check for tutorial-config.json - function checkConfig() { - server.send('vonage-app:config-check', {}); - } - if (localStorage.getItem('config-checked')) { - // if config-checked exists - // check local storage for tutorial config and load if it exists - console.log('config-checked exists'); - checkLocalStorage(); - } else { - console.log('config checked not there'); - // if config-checked doesn't exist - // - check for tutorial config file - checkConfig(); - //localStorage.setItem('config-checked', 'false'); - } + const customInstallCmdInput = astroToolbarWindow?.querySelector( + '#custom-install-command' + ) as HTMLInputElement; + customInstallCmdInput.value = + tutorial.customInstallCmd !== '' ? tutorial.customInstallCmd : ''; + customInstallCmdInput?.addEventListener('change', (event) => { + tutorial.customInstallCmd = customInstallCmdInput?.value; + saveConfig(); + }); + + const customSetupCmdInput = astroToolbarWindow?.querySelector( + '#custom-setup-command' + ) as HTMLInputElement; + customSetupCmdInput.value = + tutorial.customSetupCmd !== '' ? tutorial.customSetupCmd : ''; + customSetupCmdInput?.addEventListener('change', (event) => { + tutorial.customSetupCmd = customSetupCmdInput?.value; + saveConfig(); + }); + + const customStartCmdInput = astroToolbarWindow?.querySelector( + '#custom-start-command' + ) as HTMLInputElement; + customStartCmdInput.value = + tutorial.customStartCmd !== '' ? tutorial.customStartCmd : ''; + customStartCmdInput?.addEventListener('change', (event) => { + tutorial.customStartCmd = customStartCmdInput?.value; + saveConfig(); + }); + + // Always read tutorial-config.json from disk on toolbar open + server.send('vonage-app:config-check', {}); server.on('config-checked', (data: any) => { - console.log('config data: ', data); - // - if tutorial config file exists, set tutorial to config data, saveTutorial(), updateUI(), and set config-checked to true if (data.found) { - console.log( - 'tutorial config file exists, set tutorial to config data, saveTutorial(), updateUI()' - ); tutorial = data.tutorial; - saveTutorial(); + saveConfig(); updateUI(); - } else { - // - if tutorial config file does not exist, check local storage for tutorial config, load if it exists, and set config-checked to true - console.log( - 'config file does not exist, check local storage for tutorial config, load if it exists' - ); - checkLocalStorage(); } - localStorage.setItem('config-checked', 'true'); }); function updateUI() { @@ -182,15 +215,11 @@ export default defineToolbarApp({ } versionInput.value = tutorial.version; repositoryInput.value = tutorial.repository; + filenameInput.value = tutorial.filename; + customInstallCmdInput.value = tutorial.customInstallCmd; + customSetupCmdInput.value = tutorial.customSetupCmd; } - function checkLocalStorage() { - if (localStorage.getItem('tutorial')) { - console.log('localStorage.getItem tutorial'); - tutorial = JSON.parse(localStorage.getItem('tutorial') || '{}'); - updateUI(); - } - } const completeSpan = astroToolbarWindow?.querySelector( '#complete' @@ -208,7 +237,7 @@ export default defineToolbarApp({ panelsChecked?.forEach((panel) => { tutorial.panels.push(panel.id); }); - saveTutorial(); + saveConfig(); }); const capabilitiesForm = astroToolbarWindow?.querySelector('#capabilities'); @@ -222,11 +251,11 @@ export default defineToolbarApp({ capabilitiesChecked?.forEach((capability) => { tutorial.capabilities.push(capability.id); }); - saveTutorial(); + saveConfig(); }); - function saveTutorial() { - localStorage.setItem('tutorial', JSON.stringify(tutorial)); + function saveConfig() { + server.send('vonage-app:save-config', { tutorial }); } function refreshFilesList() { @@ -260,7 +289,7 @@ export default defineToolbarApp({ fileLi.appendChild(fileButton); fileUl.appendChild(fileLi); }); - saveTutorial(); + saveConfig(); } const fileInputError = astroToolbarWindow?.querySelector( @@ -317,7 +346,7 @@ export default defineToolbarApp({ fileLi.appendChild(fileButton); fileUl.appendChild(fileLi); }); - saveTutorial(); + saveConfig(); } const fileOpenInputError = astroToolbarWindow?.querySelector( @@ -377,7 +406,7 @@ export default defineToolbarApp({ fileLi.appendChild(fileButton); fileUl.appendChild(fileLi); }); - saveTutorial(); + saveConfig(); } const starterFileInputError = astroToolbarWindow?.querySelector( @@ -432,11 +461,9 @@ export default defineToolbarApp({ astroToolbarWindow?.querySelector( '#download-link' ) as HTMLAnchorElement - ).href = `${window.location.origin}/product_name-language-topic.zip`; + ).href = `${window.location.origin}/${tutorial.filename}.zip`; generateButton.disabled = false; completeSpan.style.display = 'block'; - // clear local storage - localStorage.clear(); } }); }, diff --git a/sources/webxr-javascript-workshop/vonage-toolbar/integration.ts b/sources/webxr-javascript-workshop/vonage-toolbar/integration.ts index b36816a0..8d35ada6 100644 --- a/sources/webxr-javascript-workshop/vonage-toolbar/integration.ts +++ b/sources/webxr-javascript-workshop/vonage-toolbar/integration.ts @@ -45,6 +45,15 @@ export default { } }); + toolbar.on('vonage-app:save-config', async (data: any) => { + try { + const configData = JSON.stringify(data.tutorial, null, 2); + await fs.writeFile('tutorial-config.json', configData); + } catch (err) { + console.error('Error saving config:', err); + } + }); + toolbar.on('vonage-app:generate', async (data: any) => { try { // create tutorial-config.json file @@ -61,7 +70,7 @@ export default { const zip = new AdmZip(); let exclude = ['node_modules', 'dist']; const sourceDir = './'; - const zipFile = './public/product_name-language-topic.zip'; + const zipFile = data.tutorial.filename === '' ? './public/product_name-language-topic.zip' : `./public/${data.tutorial.filename}.zip`; await zip.addLocalFolderPromise(sourceDir, { filter: (filePath) => !exclude.some((ex) => filePath.includes(ex)), }); diff --git a/tutorials/vonage_video_react_app-theme-customization/project/package.json b/tutorials/vonage_video_react_app-theme-customization/project/package.json index 172db3c1..0cfb4e4d 100644 --- a/tutorials/vonage_video_react_app-theme-customization/project/package.json +++ b/tutorials/vonage_video_react_app-theme-customization/project/package.json @@ -197,7 +197,7 @@ "react-dom": "19.2.4", "react-global-state-hooks": "15.0.15", "react-i18next": "15.7.4", - "react-router-dom": "6.30.3", + "react-router-dom": "7.13.0", "react-syntax-highlighter": "16.1.1", "resize-observer-polyfill": "1.5.1", "status-code-enum": "1.0.0", diff --git a/tutorials/vonage_video_react_app-theme-customization/project/yarn.lock b/tutorials/vonage_video_react_app-theme-customization/project/yarn.lock index 480cd296..bbf5b953 100644 --- a/tutorials/vonage_video_react_app-theme-customization/project/yarn.lock +++ b/tutorials/vonage_video_react_app-theme-customization/project/yarn.lock @@ -3390,11 +3390,6 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== -"@remix-run/router@1.23.2": - version "1.23.2" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.23.2.tgz#156c4b481c0bee22a19f7924728a67120de06971" - integrity sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w== - "@rolldown/pluginutils@1.0.0-rc.2": version "1.0.0-rc.2" resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.2.tgz#10324e74cb3396cb7b616042ea7e9e6aa7d8d458" @@ -6677,6 +6672,11 @@ cookie-signature@~1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.7.tgz#ab5dd7ab757c54e60f37ef6550f481c426d10454" integrity sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA== +cookie@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-1.1.1.tgz#3bb9bdfc82369db9c2f69c93c9c3ceb310c88b3c" + integrity sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ== + cookie@~0.7.1: version "0.7.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" @@ -12407,20 +12407,20 @@ react-refresh@^0.18.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.18.0.tgz#2dce97f4fe932a4d8142fa1630e475c1729c8062" integrity sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw== -react-router-dom@6.30.3: - version "6.30.3" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.30.3.tgz#42ae6dc4c7158bfb0b935f162b9621b29dddf740" - integrity sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag== +react-router-dom@7.13.0: + version "7.13.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-7.13.0.tgz#8b5f7204fadca680f0e94f207c163f0dcd1cfdf5" + integrity sha512-5CO/l5Yahi2SKC6rGZ+HDEjpjkGaG/ncEP7eWFTvFxbHP8yeeI0PxTDjimtpXYlR3b3i9/WIL4VJttPrESIf2g== dependencies: - "@remix-run/router" "1.23.2" - react-router "6.30.3" + react-router "7.13.0" -react-router@6.30.3: - version "6.30.3" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.30.3.tgz#994b3ccdbe0e81fe84d4f998100f62584dfbf1cf" - integrity sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw== +react-router@7.13.0: + version "7.13.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-7.13.0.tgz#de9484aee764f4f65b93275836ff5944d7f5bd3b" + integrity sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw== dependencies: - "@remix-run/router" "1.23.2" + cookie "^1.0.1" + set-cookie-parser "^2.6.0" react-syntax-highlighter@16.1.1: version "16.1.1" @@ -12936,6 +12936,11 @@ serve-static@~1.16.2: parseurl "~1.3.3" send "~0.19.1" +set-cookie-parser@^2.6.0: + version "2.7.2" + resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz#ccd08673a9ae5d2e44ea2a2de25089e67c7edf68" + integrity sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw== + set-function-length@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" diff --git a/tutorials/webxr-javascript-workshop/.astro/data-store.json b/tutorials/webxr-javascript-workshop/.astro/data-store.json index 44ef02d8..d27e64c4 100644 --- a/tutorials/webxr-javascript-workshop/.astro/data-store.json +++ b/tutorials/webxr-javascript-workshop/.astro/data-store.json @@ -1 +1 @@ -[["Map",1,2,9,10],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.18.1","content-config-digest","a30a942a2ceda2e1","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"where\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true,\"allowedHosts\":[]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[],\"remotePatterns\":[],\"responsiveStyles\":false},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":false,\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[null,null,null],\"rehypePlugins\":[[null,{\"experimentalHeadingIdCompat\":false}],null,[null,{\"themes\":[{\"name\":\"Night Owl No Italics\",\"type\":\"dark\",\"colors\":{\"focusBorder\":\"#122d42\",\"foreground\":\"#d6deeb\",\"disabledForeground\":\"#cccccc80\",\"descriptionForeground\":\"#d6deebb3\",\"errorForeground\":\"#ef5350\",\"icon.foreground\":\"#c5c5c5\",\"contrastActiveBorder\":null,\"contrastBorder\":\"#122d42\",\"textBlockQuote.background\":\"#7f7f7f1a\",\"textBlockQuote.border\":\"#007acc80\",\"textCodeBlock.background\":\"#4f4f4f\",\"textLink.activeForeground\":\"#3794ff\",\"textLink.foreground\":\"#3794ff\",\"textPreformat.foreground\":\"#d7ba7d\",\"textSeparator.foreground\":\"#ffffff2e\",\"editor.background\":\"#23262f\",\"editor.foreground\":\"#d6deeb\",\"editorLineNumber.foreground\":\"#4b6479\",\"editorLineNumber.activeForeground\":\"#c5e4fd\",\"editorActiveLineNumber.foreground\":\"#c6c6c6\",\"editor.selectionBackground\":\"#1d3b53\",\"editor.inactiveSelectionBackground\":\"#7e57c25a\",\"editor.selectionHighlightBackground\":\"#5f7e9779\",\"editorError.foreground\":\"#ef5350\",\"editorWarning.foreground\":\"#b39554\",\"editorInfo.foreground\":\"#3794ff\",\"editorHint.foreground\":\"#eeeeeeb2\",\"problemsErrorIcon.foreground\":\"#ef5350\",\"problemsWarningIcon.foreground\":\"#b39554\",\"problemsInfoIcon.foreground\":\"#3794ff\",\"editor.findMatchBackground\":\"#5f7e9779\",\"editor.findMatchHighlightBackground\":\"#1085bb5d\",\"editor.findRangeHighlightBackground\":\"#3a3d4166\",\"editorLink.activeForeground\":\"#4e94ce\",\"editorLightBulb.foreground\":\"#ffcc00\",\"editorLightBulbAutoFix.foreground\":\"#75beff\",\"diffEditor.insertedTextBackground\":\"#99b76d23\",\"diffEditor.insertedTextBorder\":\"#c5e47833\",\"diffEditor.removedTextBackground\":\"#ef535033\",\"diffEditor.removedTextBorder\":\"#ef53504d\",\"diffEditor.insertedLineBackground\":\"#9bb95533\",\"diffEditor.removedLineBackground\":\"#ff000033\",\"editorStickyScroll.background\":\"#011627\",\"editorStickyScrollHover.background\":\"#2a2d2e\",\"editorInlayHint.background\":\"#5f7e97cc\",\"editorInlayHint.foreground\":\"#ffffff\",\"editorInlayHint.typeBackground\":\"#5f7e97cc\",\"editorInlayHint.typeForeground\":\"#ffffff\",\"editorInlayHint.parameterBackground\":\"#5f7e97cc\",\"editorInlayHint.parameterForeground\":\"#ffffff\",\"editorPane.background\":\"#011627\",\"editorGroup.emptyBackground\":\"#011627\",\"editorGroup.focusedEmptyBorder\":null,\"editorGroupHeader.tabsBackground\":\"var(--sl-color-black)\",\"editorGroupHeader.tabsBorder\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"editorGroupHeader.noTabsBackground\":\"#011627\",\"editorGroupHeader.border\":null,\"editorGroup.border\":\"#011627\",\"editorGroup.dropBackground\":\"#7e57c273\",\"editorGroup.dropIntoPromptForeground\":\"#d6deeb\",\"editorGroup.dropIntoPromptBackground\":\"#021320\",\"editorGroup.dropIntoPromptBorder\":null,\"sideBySideEditor.horizontalBorder\":\"#011627\",\"sideBySideEditor.verticalBorder\":\"#011627\",\"scrollbar.shadow\":\"#010b14\",\"scrollbarSlider.background\":\"#ffffff17\",\"scrollbarSlider.hoverBackground\":\"#ffffff40\",\"scrollbarSlider.activeBackground\":\"#084d8180\",\"panel.background\":\"#011627\",\"panel.border\":\"#5f7e97\",\"panelTitle.activeBorder\":\"#5f7e97\",\"panelTitle.activeForeground\":\"#ffffffcc\",\"panelTitle.inactiveForeground\":\"#d6deeb80\",\"panelSectionHeader.background\":\"#80808051\",\"terminal.background\":\"#011627\",\"widget.shadow\":\"#011627\",\"editorWidget.background\":\"#021320\",\"editorWidget.foreground\":\"#d6deeb\",\"editorWidget.border\":\"#5f7e97\",\"quickInput.background\":\"#021320\",\"quickInput.foreground\":\"#d6deeb\",\"quickInputTitle.background\":\"#ffffff1a\",\"pickerGroup.foreground\":\"#d1aaff\",\"pickerGroup.border\":\"#011627\",\"editor.hoverHighlightBackground\":\"#7e57c25a\",\"editorHoverWidget.background\":\"#011627\",\"editorHoverWidget.foreground\":\"#d6deeb\",\"editorHoverWidget.border\":\"#5f7e97\",\"editorHoverWidget.statusBarBackground\":\"#011a2f\",\"titleBar.activeBackground\":\"var(--sl-color-black)\",\"titleBar.activeForeground\":\"var(--sl-color-text)\",\"titleBar.inactiveBackground\":\"#010e1a\",\"titleBar.inactiveForeground\":\"#eeefff99\",\"titleBar.border\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"toolbar.hoverBackground\":\"#5a5d5e50\",\"toolbar.activeBackground\":\"#63666750\",\"tab.activeBackground\":\"#0b2942\",\"tab.unfocusedActiveBackground\":\"#0b2942\",\"tab.inactiveBackground\":\"#01111d\",\"tab.unfocusedInactiveBackground\":\"#01111d\",\"tab.activeForeground\":\"var(--sl-color-text)\",\"tab.inactiveForeground\":\"#5f7e97\",\"tab.unfocusedActiveForeground\":\"#5f7e97\",\"tab.unfocusedInactiveForeground\":\"#5f7e97\",\"tab.hoverBackground\":null,\"tab.unfocusedHoverBackground\":null,\"tab.hoverForeground\":null,\"tab.unfocusedHoverForeground\":null,\"tab.border\":\"#272b3b\",\"tab.lastPinnedBorder\":\"#585858\",\"tab.activeBorder\":\"transparent\",\"tab.unfocusedActiveBorder\":\"#262a39\",\"tab.activeBorderTop\":\"var(--sl-color-accent-high)\",\"tab.unfocusedActiveBorderTop\":null,\"tab.hoverBorder\":null,\"tab.unfocusedHoverBorder\":null,\"tab.activeModifiedBorder\":\"#3399cc\",\"tab.inactiveModifiedBorder\":\"#3399cc80\",\"tab.unfocusedActiveModifiedBorder\":\"#3399cc80\",\"tab.unfocusedInactiveModifiedBorder\":\"#3399cc40\",\"badge.background\":\"#5f7e97\",\"badge.foreground\":\"#ffffff\",\"button.background\":\"#7e57c2cc\",\"button.foreground\":\"#ffffffcc\",\"button.border\":\"#122d42\",\"button.separator\":\"#ffffff52\",\"button.hoverBackground\":\"#7e57c2\",\"button.secondaryBackground\":\"#3a3d41\",\"button.secondaryForeground\":\"#ffffff\",\"button.secondaryHoverBackground\":\"#46494e\",\"dropdown.background\":\"#011627\",\"dropdown.foreground\":\"#ffffffcc\",\"dropdown.border\":\"#5f7e97\",\"list.activeSelectionBackground\":\"#234d708c\",\"list.activeSelectionForeground\":\"#ffffff\",\"tree.indentGuidesStroke\":\"#585858\",\"input.background\":\"#0b253a\",\"input.foreground\":\"#ffffffcc\",\"input.placeholderForeground\":\"#5f7e97\",\"inputOption.activeBorder\":\"#ffffffcc\",\"inputOption.hoverBackground\":\"#5a5d5e80\",\"inputOption.activeBackground\":\"#122d4266\",\"inputOption.activeForeground\":\"#ffffff\",\"inputValidation.infoBackground\":\"#00589ef2\",\"inputValidation.infoBorder\":\"#64b5f6\",\"inputValidation.warningBackground\":\"#675700f2\",\"inputValidation.warningBorder\":\"#ffca28\",\"inputValidation.errorBackground\":\"#ab0300f2\",\"inputValidation.errorBorder\":\"#ef5350\",\"keybindingLabel.background\":\"#8080802b\",\"keybindingLabel.foreground\":\"#cccccc\",\"keybindingLabel.border\":\"#33333399\",\"keybindingLabel.bottomBorder\":\"#44444499\",\"menu.foreground\":\"#ffffffcc\",\"menu.background\":\"#011627\",\"menu.selectionForeground\":\"#ffffff\",\"menu.selectionBackground\":\"#234d708c\",\"menu.separatorBackground\":\"#606060\",\"editor.snippetTabstopHighlightBackground\":\"#7c7c74c\",\"editor.snippetFinalTabstopHighlightBorder\":\"#525252\",\"terminal.ansiBlack\":\"#011627\",\"terminal.ansiRed\":\"#ef5350\",\"terminal.ansiGreen\":\"#22da6e\",\"terminal.ansiYellow\":\"#c5e478\",\"terminal.ansiBlue\":\"#82aaff\",\"terminal.ansiMagenta\":\"#c792ea\",\"terminal.ansiCyan\":\"#21c7a8\",\"terminal.ansiWhite\":\"#ffffff\",\"terminal.ansiBrightBlack\":\"#575656\",\"terminal.ansiBrightRed\":\"#ef5350\",\"terminal.ansiBrightGreen\":\"#22da6e\",\"terminal.ansiBrightYellow\":\"#ffeb95\",\"terminal.ansiBrightBlue\":\"#82aaff\",\"terminal.ansiBrightMagenta\":\"#c792ea\",\"terminal.ansiBrightCyan\":\"#7fdbca\",\"terminal.ansiBrightWhite\":\"#ffffff\",\"selection.background\":\"#4373c2\",\"input.border\":\"#5f7e97\",\"punctuation.definition.generic.begin.html\":\"#ef5350f2\",\"progress.background\":\"#7e57c2\",\"breadcrumb.foreground\":\"#a599e9\",\"breadcrumb.focusForeground\":\"#ffffff\",\"breadcrumb.activeSelectionForeground\":\"#ffffff\",\"breadcrumbPicker.background\":\"#001122\",\"list.invalidItemForeground\":\"#975f94\",\"list.dropBackground\":\"#011627\",\"list.focusBackground\":\"#010d18\",\"list.focusForeground\":\"#ffffff\",\"list.highlightForeground\":\"#ffffff\",\"list.hoverBackground\":\"#011627\",\"list.hoverForeground\":\"#ffffff\",\"list.inactiveSelectionBackground\":\"#0e293f\",\"list.inactiveSelectionForeground\":\"#5f7e97\",\"activityBar.background\":\"#011627\",\"activityBar.dropBackground\":\"#5f7e97\",\"activityBar.foreground\":\"#5f7e97\",\"activityBar.border\":\"#011627\",\"activityBarBadge.background\":\"#44596b\",\"activityBarBadge.foreground\":\"#ffffff\",\"sideBar.background\":\"#011627\",\"sideBar.foreground\":\"#89a4bb\",\"sideBar.border\":\"#011627\",\"sideBarTitle.foreground\":\"#5f7e97\",\"sideBarSectionHeader.background\":\"#011627\",\"sideBarSectionHeader.foreground\":\"#5f7e97\",\"editorCursor.foreground\":\"#80a4c2\",\"editor.wordHighlightBackground\":\"#f6bbe533\",\"editor.wordHighlightStrongBackground\":\"#e2a2f433\",\"editor.lineHighlightBackground\":\"#0003\",\"editor.rangeHighlightBackground\":\"#7e57c25a\",\"editorIndentGuide.background\":\"#5e81ce52\",\"editorIndentGuide.activeBackground\":\"#7e97ac\",\"editorRuler.foreground\":\"#5e81ce52\",\"editorCodeLens.foreground\":\"#5e82ceb4\",\"editorBracketMatch.background\":\"#5f7e974d\",\"editorOverviewRuler.currentContentForeground\":\"#7e57c2\",\"editorOverviewRuler.incomingContentForeground\":\"#7e57c2\",\"editorOverviewRuler.commonContentForeground\":\"#7e57c2\",\"editorGutter.background\":\"#011627\",\"editorGutter.modifiedBackground\":\"#e2b93d\",\"editorGutter.addedBackground\":\"#9ccc65\",\"editorGutter.deletedBackground\":\"#ef5350\",\"editorSuggestWidget.background\":\"#2c3043\",\"editorSuggestWidget.border\":\"#2b2f40\",\"editorSuggestWidget.foreground\":\"#d6deeb\",\"editorSuggestWidget.highlightForeground\":\"#ffffff\",\"editorSuggestWidget.selectedBackground\":\"#5f7e97\",\"debugExceptionWidget.background\":\"#011627\",\"debugExceptionWidget.border\":\"#5f7e97\",\"editorMarkerNavigation.background\":\"#0b2942\",\"editorMarkerNavigationError.background\":\"#ef5350\",\"editorMarkerNavigationWarning.background\":\"#ffca28\",\"peekView.border\":\"#5f7e97\",\"peekViewEditor.background\":\"#011627\",\"peekViewEditor.matchHighlightBackground\":\"#7e57c25a\",\"peekViewResult.background\":\"#011627\",\"peekViewResult.fileForeground\":\"#5f7e97\",\"peekViewResult.lineForeground\":\"#5f7e97\",\"peekViewResult.matchHighlightBackground\":\"#ffffffcc\",\"peekViewResult.selectionBackground\":\"#2e3250\",\"peekViewResult.selectionForeground\":\"#5f7e97\",\"peekViewTitle.background\":\"#011627\",\"peekViewTitleDescription.foreground\":\"#697098\",\"peekViewTitleLabel.foreground\":\"#5f7e97\",\"merge.currentHeaderBackground\":\"#5f7e97\",\"merge.incomingHeaderBackground\":\"#7e57c25a\",\"statusBar.background\":\"#011627\",\"statusBar.foreground\":\"#5f7e97\",\"statusBar.border\":\"#262a39\",\"statusBar.debuggingBackground\":\"#202431\",\"statusBar.debuggingBorder\":\"#1f2330\",\"statusBar.noFolderBackground\":\"#011627\",\"statusBar.noFolderBorder\":\"#25293a\",\"statusBarItem.activeBackground\":\"#202431\",\"statusBarItem.hoverBackground\":\"#202431\",\"statusBarItem.prominentBackground\":\"#202431\",\"statusBarItem.prominentHoverBackground\":\"#202431\",\"notifications.background\":\"#01111d\",\"notifications.border\":\"#262a39\",\"notificationCenter.border\":\"#262a39\",\"notificationToast.border\":\"#262a39\",\"notifications.foreground\":\"#ffffffcc\",\"notificationLink.foreground\":\"#80cbc4\",\"extensionButton.prominentForeground\":\"#ffffffcc\",\"extensionButton.prominentBackground\":\"#7e57c2cc\",\"extensionButton.prominentHoverBackground\":\"#7e57c2\",\"terminal.selectionBackground\":\"#1b90dd4d\",\"terminalCursor.background\":\"#234d70\",\"debugToolBar.background\":\"#011627\",\"welcomePage.buttonBackground\":\"#011627\",\"welcomePage.buttonHoverBackground\":\"#011627\",\"walkThrough.embeddedEditorBackground\":\"#011627\",\"gitDecoration.modifiedResourceForeground\":\"#a2bffc\",\"gitDecoration.deletedResourceForeground\":\"#ef535090\",\"gitDecoration.untrackedResourceForeground\":\"#c5e478ff\",\"gitDecoration.ignoredResourceForeground\":\"#395a75\",\"gitDecoration.conflictingResourceForeground\":\"#ffeb95cc\",\"source.elm\":\"#5f7e97\",\"string.quoted.single.js\":\"#ffffff\",\"meta.objectliteral.js\":\"#82aaff\"},\"fg\":\"#d6deeb\",\"bg\":\"#23262f\",\"semanticHighlighting\":false,\"settings\":[{\"name\":\"Changed\",\"scope\":[\"markup.changed\",\"meta.diff.header.git\",\"meta.diff.header.from-file\",\"meta.diff.header.to-file\"],\"settings\":{\"foreground\":\"#a2bffc\"}},{\"name\":\"Deleted\",\"scope\":[\"markup.deleted.diff\"],\"settings\":{\"foreground\":\"#f27775fe\"}},{\"name\":\"Inserted\",\"scope\":[\"markup.inserted.diff\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Global settings\",\"settings\":{\"background\":\"#011627\",\"foreground\":\"#d6deeb\"}},{\"name\":\"Comment\",\"scope\":[\"comment\"],\"settings\":{\"foreground\":\"#919f9f\",\"fontStyle\":\"\"}},{\"name\":\"String\",\"scope\":[\"string\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"String Quoted\",\"scope\":[\"string.quoted\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"Support Constant Math\",\"scope\":[\"support.constant.math\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Number\",\"scope\":[\"constant.numeric\",\"constant.character.numeric\"],\"settings\":{\"foreground\":\"#f78c6c\",\"fontStyle\":\"\"}},{\"name\":\"Built-in constant\",\"scope\":[\"constant.language\",\"punctuation.definition.constant\",\"variable.other.constant\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"User-defined constant\",\"scope\":[\"constant.character\",\"constant.other\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Constant Character Escape\",\"scope\":[\"constant.character.escape\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"RegExp String\",\"scope\":[\"string.regexp\",\"string.regexp keyword.other\"],\"settings\":{\"foreground\":\"#5ca7e4\"}},{\"name\":\"Comma in functions\",\"scope\":[\"meta.function punctuation.separator.comma\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"Variable\",\"scope\":[\"variable\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Keyword\",\"scope\":[\"punctuation.accessor\",\"keyword\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Storage\",\"scope\":[\"storage\",\"meta.var.expr\",\"meta.class meta.method.declaration meta.var.expr storage.type.js\",\"storage.type.property.js\",\"storage.type.property.ts\",\"storage.type.property.tsx\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type.function.arrow.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Class name\",\"scope\":[\"entity.name.class\",\"meta.class entity.name.type.class\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Inherited class\",\"scope\":[\"entity.other.inherited-class\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Function name\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Meta Tag\",\"scope\":[\"punctuation.definition.tag\",\"meta.tag\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"HTML Tag names\",\"scope\":[\"entity.name.tag\",\"meta.tag.other.html\",\"meta.tag.other.js\",\"meta.tag.other.tsx\",\"entity.name.tag.tsx\",\"entity.name.tag.js\",\"entity.name.tag\",\"meta.tag.js\",\"meta.tag.tsx\",\"meta.tag.html\"],\"settings\":{\"foreground\":\"#caece6\",\"fontStyle\":\"\"}},{\"name\":\"Tag attribute\",\"scope\":[\"entity.other.attribute-name\"],\"settings\":{\"fontStyle\":\"\",\"foreground\":\"#c5e478\"}},{\"name\":\"Entity Name Tag Custom\",\"scope\":[\"entity.name.tag.custom\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Library (function & constant)\",\"scope\":[\"support.function\",\"support.constant\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Support Constant Property Value meta\",\"scope\":[\"support.constant.meta.property-value\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Library class/type\",\"scope\":[\"support.type\",\"support.class\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Support Variable DOM\",\"scope\":[\"support.variable.dom\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Invalid\",\"scope\":[\"invalid\"],\"settings\":{\"background\":\"#ff2c83\",\"foreground\":\"#ffffff\"}},{\"name\":\"Invalid deprecated\",\"scope\":[\"invalid.deprecated\"],\"settings\":{\"foreground\":\"#ffffff\",\"background\":\"#d3423e\"}},{\"name\":\"Keyword Operator\",\"scope\":[\"keyword.operator\"],\"settings\":{\"foreground\":\"#7fdbca\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Relational\",\"scope\":[\"keyword.operator.relational\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Assignment\",\"scope\":[\"keyword.operator.assignment\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Arithmetic\",\"scope\":[\"keyword.operator.arithmetic\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Bitwise\",\"scope\":[\"keyword.operator.bitwise\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Increment\",\"scope\":[\"keyword.operator.increment\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Ternary\",\"scope\":[\"keyword.operator.ternary\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Double-Slashed Comment\",\"scope\":[\"comment.line.double-slash\"],\"settings\":{\"foreground\":\"#919f9f\"}},{\"name\":\"Object\",\"scope\":[\"object\"],\"settings\":{\"foreground\":\"#cdebf7\"}},{\"name\":\"Null\",\"scope\":[\"constant.language.null\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Meta Brace\",\"scope\":[\"meta.brace\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Meta Delimiter Period\",\"scope\":[\"meta.delimiter.period\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Punctuation Definition String\",\"scope\":[\"punctuation.definition.string\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Punctuation Definition String Markdown\",\"scope\":[\"punctuation.definition.string.begin.markdown\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Boolean\",\"scope\":[\"constant.language.boolean\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Object Comma\",\"scope\":[\"object.comma\"],\"settings\":{\"foreground\":\"#ffffff\"}},{\"name\":\"Variable Parameter Function\",\"scope\":[\"variable.parameter.function\"],\"settings\":{\"foreground\":\"#7fdbca\",\"fontStyle\":\"\"}},{\"name\":\"Support Type Property Name & entity name tags\",\"scope\":[\"support.type.vendor.property-name\",\"support.constant.vendor.property-value\",\"support.type.property-name\",\"meta.property-list entity.name.tag\"],\"settings\":{\"foreground\":\"#80cbc4\",\"fontStyle\":\"\"}},{\"name\":\"Entity Name tag reference in stylesheets\",\"scope\":[\"meta.property-list entity.name.tag.reference\"],\"settings\":{\"foreground\":\"#57eaf1\"}},{\"name\":\"Constant Other Color RGB Value Punctuation Definition Constant\",\"scope\":[\"constant.other.color.rgb-value punctuation.definition.constant\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Constant Other Color\",\"scope\":[\"constant.other.color\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Keyword Other Unit\",\"scope\":[\"keyword.other.unit\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Meta Selector\",\"scope\":[\"meta.selector\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Entity Other Attribute Name Id\",\"scope\":[\"entity.other.attribute-name.id\"],\"settings\":{\"foreground\":\"#fad430\"}},{\"name\":\"Meta Property Name\",\"scope\":[\"meta.property-name\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Doctypes\",\"scope\":[\"entity.name.tag.doctype\",\"meta.tag.sgml.doctype\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Punctuation Definition Parameters\",\"scope\":[\"punctuation.definition.parameters\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Keyword Control Operator\",\"scope\":[\"keyword.control.operator\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Keyword Operator Logical\",\"scope\":[\"keyword.operator.logical\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Variable Instances\",\"scope\":[\"variable.instance\",\"variable.other.instance\",\"variable.readwrite.instance\",\"variable.other.readwrite.instance\",\"variable.other.property\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Variable Property Other object property\",\"scope\":[\"variable.other.object.property\"],\"settings\":{\"foreground\":\"#faf39f\",\"fontStyle\":\"\"}},{\"name\":\"Variable Property Other object\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Entity Name Function\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#82aaff\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Comparison, returns, imports, and Keyword Operator Ruby\",\"scope\":[\"keyword.control.conditional.js\",\"keyword.operator.comparison\",\"keyword.control.flow.js\",\"keyword.control.flow.ts\",\"keyword.control.flow.tsx\",\"keyword.control.ruby\",\"keyword.control.def.ruby\",\"keyword.control.loop.js\",\"keyword.control.loop.ts\",\"keyword.control.import.js\",\"keyword.control.import.ts\",\"keyword.control.import.tsx\",\"keyword.control.from.js\",\"keyword.control.from.ts\",\"keyword.control.from.tsx\",\"keyword.control.conditional.js\",\"keyword.control.conditional.ts\",\"keyword.control.switch.js\",\"keyword.control.switch.ts\",\"keyword.operator.instanceof.js\",\"keyword.operator.expression.instanceof.ts\",\"keyword.operator.expression.instanceof.tsx\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords\",\"scope\":[\"support.constant\",\"keyword.other.special-method\",\"keyword.other.new\",\"keyword.other.debugger\",\"keyword.control\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Support Function\",\"scope\":[\"support.function\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Invalid Broken\",\"scope\":[\"invalid.broken\"],\"settings\":{\"foreground\":\"#989da0\",\"background\":\"#F78C6C\"}},{\"name\":\"Invalid Unimplemented\",\"scope\":[\"invalid.unimplemented\"],\"settings\":{\"background\":\"#8BD649\",\"foreground\":\"#ffffff\"}},{\"name\":\"Invalid Illegal\",\"scope\":[\"invalid.illegal\"],\"settings\":{\"foreground\":\"#ffffff\",\"background\":\"#ec5f67\"}},{\"name\":\"Language Variable\",\"scope\":[\"variable.language\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Support Variable Property\",\"scope\":[\"support.variable.property\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Variable Function\",\"scope\":[\"variable.function\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Variable Interpolation\",\"scope\":[\"variable.interpolation\"],\"settings\":{\"foreground\":\"#ef787f\"}},{\"name\":\"Meta Function Call\",\"scope\":[\"meta.function-call\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Punctuation Section Embedded\",\"scope\":[\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#e2817f\"}},{\"name\":\"Punctuation Tweaks\",\"scope\":[\"punctuation.terminator.expression\",\"punctuation.definition.arguments\",\"punctuation.definition.array\",\"punctuation.section.array\",\"meta.array\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"More Punctuation Tweaks\",\"scope\":[\"punctuation.definition.list.begin\",\"punctuation.definition.list.end\",\"punctuation.separator.arguments\",\"punctuation.definition.list\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Template Strings\",\"scope\":[\"string.template meta.template.expression\"],\"settings\":{\"foreground\":\"#e2817f\"}},{\"name\":\"Backticks(``) in Template Strings\",\"scope\":[\"string.template punctuation.definition.string\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Italics\",\"scope\":[\"italic\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"italic\"}},{\"name\":\"Bold\",\"scope\":[\"bold\"],\"settings\":{\"foreground\":\"#c5e478\",\"fontStyle\":\"bold\"}},{\"name\":\"Quote\",\"scope\":[\"quote\"],\"settings\":{\"foreground\":\"#969bb7\",\"fontStyle\":\"\"}},{\"name\":\"Raw Code\",\"scope\":[\"raw\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"CoffeeScript Variable Assignment\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#31e1eb\"}},{\"name\":\"CoffeeScript Parameter Function\",\"scope\":[\"variable.parameter.function.coffee\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"CoffeeScript Assignments\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"C# Readwrite Variables\",\"scope\":[\"variable.other.readwrite.cs\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C# Classes & Storage types\",\"scope\":[\"entity.name.type.class.cs\",\"storage.type.cs\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"C# Namespaces\",\"scope\":[\"entity.name.type.namespace.cs\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"C# Unquoted String Zone\",\"scope\":[\"string.unquoted.preprocessor.message.cs\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C# Region\",\"scope\":[\"punctuation.separator.hash.cs\",\"keyword.preprocessor.region.cs\",\"keyword.preprocessor.endregion.cs\"],\"settings\":{\"foreground\":\"#ffcb8b\",\"fontStyle\":\"bold\"}},{\"name\":\"C# Other Variables\",\"scope\":[\"variable.other.object.cs\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"C# Enum\",\"scope\":[\"entity.name.type.enum.cs\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Dart String\",\"scope\":[\"string.interpolated.single.dart\",\"string.interpolated.double.dart\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Dart Class\",\"scope\":[\"support.class.dart\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Tag names in Stylesheets\",\"scope\":[\"entity.name.tag.css\",\"entity.name.tag.less\",\"entity.name.tag.custom.css\",\"support.constant.property-value.css\"],\"settings\":{\"foreground\":\"#ff6d6d\",\"fontStyle\":\"\"}},{\"name\":\"Wildcard(*) selector in Stylesheets\",\"scope\":[\"entity.name.tag.wildcard.css\",\"entity.name.tag.wildcard.less\",\"entity.name.tag.wildcard.scss\",\"entity.name.tag.wildcard.sass\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"CSS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Attribute Name for CSS\",\"scope\":[\"meta.attribute-selector.css entity.other.attribute-name.attribute\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Elixir Classes\",\"scope\":[\"source.elixir support.type.elixir\",\"source.elixir meta.module.elixir entity.name.class.elixir\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Elixir Functions\",\"scope\":[\"source.elixir entity.name.function\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir Constants\",\"scope\":[\"source.elixir constant.other.symbol.elixir\",\"source.elixir constant.other.keywords.elixir\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Elixir String Punctuations\",\"scope\":[\"source.elixir punctuation.definition.string\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir\",\"scope\":[\"source.elixir variable.other.readwrite.module.elixir\",\"source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir Binary Punctuations\",\"scope\":[\"source.elixir .punctuation.binary.elixir\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Closure Constant Keyword\",\"scope\":[\"constant.keyword.clojure\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Go Function Calls\",\"scope\":[\"source.go meta.function-call.go\"],\"settings\":{\"foreground\":\"#dddddd\"}},{\"name\":\"Go Keywords\",\"scope\":[\"source.go keyword.package.go\",\"source.go keyword.import.go\",\"source.go keyword.function.go\",\"source.go keyword.type.go\",\"source.go keyword.struct.go\",\"source.go keyword.interface.go\",\"source.go keyword.const.go\",\"source.go keyword.var.go\",\"source.go keyword.map.go\",\"source.go keyword.channel.go\",\"source.go keyword.control.go\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Go Constants e.g. nil, string format (%s, %d, etc.)\",\"scope\":[\"source.go constant.language.go\",\"source.go constant.other.placeholder.go\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"C++ Functions\",\"scope\":[\"entity.name.function.preprocessor.cpp\",\"entity.scope.name.cpp\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"C++ Meta Namespace\",\"scope\":[\"meta.namespace-block.cpp\"],\"settings\":{\"foreground\":\"#e0dec6\"}},{\"name\":\"C++ Language Primitive Storage\",\"scope\":[\"storage.type.language.primitive.cpp\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"C++ Preprocessor Macro\",\"scope\":[\"meta.preprocessor.macro.cpp\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C++ Variable Parameter\",\"scope\":[\"variable.parameter\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Powershell Variables\",\"scope\":[\"variable.other.readwrite.powershell\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Powershell Function\",\"scope\":[\"support.function.powershell\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"ID Attribute Name in HTML\",\"scope\":[\"entity.other.attribute-name.id.html\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"HTML Punctuation Definition Tag\",\"scope\":[\"punctuation.definition.tag.html\"],\"settings\":{\"foreground\":\"#6ae9f0\"}},{\"name\":\"HTML Doctype\",\"scope\":[\"meta.tag.sgml.doctype.html\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Classes\",\"scope\":[\"meta.class entity.name.type.class.js\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"JavaScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.js\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"JavaScript Terminator\",\"scope\":[\"terminator.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Meta Punctuation Definition\",\"scope\":[\"meta.js punctuation.definition.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Entity Names in Code Documentations\",\"scope\":[\"entity.name.type.instance.jsdoc\",\"entity.name.type.instance.phpdoc\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"Other Variables in Code Documentations\",\"scope\":[\"variable.other.jsdoc\",\"variable.other.phpdoc\"],\"settings\":{\"foreground\":\"#78ccf0\"}},{\"name\":\"JavaScript module imports and exports\",\"scope\":[\"variable.other.meta.import.js\",\"meta.import.js variable.other\",\"variable.other.meta.export.js\",\"meta.export.js variable.other\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Variable Parameter Function\",\"scope\":[\"variable.parameter.function.js\"],\"settings\":{\"foreground\":\"#8b96ea\"}},{\"name\":\"JavaScript[React] Variable Other Object\",\"scope\":[\"variable.other.object.js\",\"variable.other.object.jsx\",\"variable.object.property.js\",\"variable.object.property.jsx\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Variables\",\"scope\":[\"variable.js\",\"variable.other.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Entity Name Type\",\"scope\":[\"entity.name.type.js\",\"entity.name.type.module.js\"],\"settings\":{\"foreground\":\"#ffcb8b\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Support Classes\",\"scope\":[\"support.class.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JSON Property Names\",\"scope\":[\"support.type.property-name.json\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"JSON Support Constants\",\"scope\":[\"support.constant.json\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"JSON Property values (string)\",\"scope\":[\"meta.structure.dictionary.value.json string.quoted.double\"],\"settings\":{\"foreground\":\"#c789d6\"}},{\"name\":\"Strings in JSON values\",\"scope\":[\"string.quoted.double.json punctuation.definition.string.json\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Specific JSON Property values like null\",\"scope\":[\"meta.structure.dictionary.json meta.structure.dictionary.value constant.language\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"JavaScript Other Variable\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Ruby Variables\",\"scope\":[\"variable.other.ruby\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Ruby Class\",\"scope\":[\"entity.name.type.class.ruby\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"Ruby Hashkeys\",\"scope\":[\"constant.language.symbol.hashkey.ruby\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"LESS Tag names\",\"scope\":[\"entity.name.tag.less\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"LESS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Attribute Name for LESS\",\"scope\":[\"meta.attribute-selector.less entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Markdown Headings\",\"scope\":[\"markup.heading.markdown\",\"markup.heading.setext.1.markdown\",\"markup.heading.setext.2.markdown\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown Italics\",\"scope\":[\"markup.italic.markdown\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"italic\"}},{\"name\":\"Markdown Bold\",\"scope\":[\"markup.bold.markdown\"],\"settings\":{\"foreground\":\"#c5e478\",\"fontStyle\":\"bold\"}},{\"name\":\"Markdown Quote + others\",\"scope\":[\"markup.quote.markdown\"],\"settings\":{\"foreground\":\"#969bb7\",\"fontStyle\":\"\"}},{\"name\":\"Markdown Raw Code + others\",\"scope\":[\"markup.inline.raw.markdown\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Markdown Links\",\"scope\":[\"markup.underline.link.markdown\",\"markup.underline.link.image.markdown\"],\"settings\":{\"foreground\":\"#ff869a\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Link Title and Description\",\"scope\":[\"string.other.link.title.markdown\",\"string.other.link.description.markdown\"],\"settings\":{\"foreground\":\"#d6deeb\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Punctuation\",\"scope\":[\"punctuation.definition.string.markdown\",\"punctuation.definition.string.begin.markdown\",\"punctuation.definition.string.end.markdown\",\"meta.link.inline.markdown punctuation.definition.string\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown MetaData Punctuation\",\"scope\":[\"punctuation.definition.metadata.markdown\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Markdown List Punctuation\",\"scope\":[\"beginning.punctuation.definition.list.markdown\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown Inline Raw String\",\"scope\":[\"markup.inline.raw.string.markdown\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"PHP Variables\",\"scope\":[\"variable.other.php\"],\"settings\":{\"foreground\":\"#bec5d4\"}},{\"name\":\"Support Classes in PHP\",\"scope\":[\"support.class.php\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Punctuations in PHP function calls\",\"scope\":[\"meta.function-call.php punctuation\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"PHP Global Variables\",\"scope\":[\"variable.other.global.php\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Declaration Punctuation in PHP Global Variables\",\"scope\":[\"variable.other.global.php punctuation.definition.variable\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Language Constants in Python\",\"scope\":[\"constant.language.python\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Python Function Parameter and Arguments\",\"scope\":[\"variable.parameter.function.python\",\"meta.function-call.arguments.python\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Python Function Call\",\"scope\":[\"meta.function-call.python\",\"meta.function-call.generic.python\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"Punctuations in Python\",\"scope\":[\"punctuation.python\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Decorator Functions in Python\",\"scope\":[\"entity.name.function.decorator.python\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Python Language Variable\",\"scope\":[\"source.python variable.language.special\"],\"settings\":{\"foreground\":\"#8eace3\"}},{\"name\":\"Python import control keyword\",\"scope\":[\"keyword.control\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"SCSS Variable\",\"scope\":[\"variable.scss\",\"variable.sass\",\"variable.parameter.url.scss\",\"variable.parameter.url.sass\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#bec5d4\"}},{\"name\":\"Attribute Name for SASS\",\"scope\":[\"meta.attribute-selector.scss entity.other.attribute-name.attribute\",\"meta.attribute-selector.sass entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Tag names in SASS\",\"scope\":[\"entity.name.tag.scss\",\"entity.name.tag.sass\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"SASS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.scss\",\"keyword.other.unit.sass\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"TypeScript[React] Variables and Object Properties\",\"scope\":[\"variable.other.readwrite.alias.ts\",\"variable.other.readwrite.alias.tsx\",\"variable.other.readwrite.ts\",\"variable.other.readwrite.tsx\",\"variable.other.object.ts\",\"variable.other.object.tsx\",\"variable.object.property.ts\",\"variable.object.property.tsx\",\"variable.other.ts\",\"variable.other.tsx\",\"variable.tsx\",\"variable.ts\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript[React] Entity Name Types\",\"scope\":[\"entity.name.type.ts\",\"entity.name.type.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript[React] Node Classes\",\"scope\":[\"support.class.node.ts\",\"support.class.node.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"TypeScript[React] Entity Name Types as Parameters\",\"scope\":[\"meta.type.parameters.ts entity.name.type\",\"meta.type.parameters.tsx entity.name.type\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"TypeScript[React] Import/Export Punctuations\",\"scope\":[\"meta.import.ts punctuation.definition.block\",\"meta.import.tsx punctuation.definition.block\",\"meta.export.ts punctuation.definition.block\",\"meta.export.tsx punctuation.definition.block\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.decorator punctuation.decorator.ts\",\"meta.decorator punctuation.decorator.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.tag.js meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"YAML Entity Name Tags\",\"scope\":[\"entity.name.tag.yaml\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"JavaScript Variable Other ReadWrite\",\"scope\":[\"variable.other.readwrite.js\",\"variable.parameter\"],\"settings\":{\"foreground\":\"#d7dbe0\"}},{\"name\":\"Support Class Component\",\"scope\":[\"support.class.component.js\",\"support.class.component.tsx\"],\"settings\":{\"foreground\":\"#f78c6c\",\"fontStyle\":\"\"}},{\"name\":\"Text nested in React tags\",\"scope\":[\"meta.jsx.children\",\"meta.jsx.children.js\",\"meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript Classes\",\"scope\":[\"meta.class entity.name.type.class.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript Entity Name Type\",\"scope\":[\"entity.name.type.tsx\",\"entity.name.type.module.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript Class Variable Keyword\",\"scope\":[\"meta.class.ts meta.var.expr.ts storage.type.ts\",\"meta.class.tsx meta.var.expr.tsx storage.type.tsx\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"TypeScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.ts\",\"meta.method.declaration storage.type.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"normalize font style of certain components\",\"scope\":[\"meta.property-list.css meta.property-value.css variable.other.less\",\"meta.property-list.scss variable.scss\",\"meta.property-list.sass variable.sass\",\"meta.brace\",\"keyword.operator.operator\",\"keyword.operator.or.regexp\",\"keyword.operator.expression.in\",\"keyword.operator.relational\",\"keyword.operator.assignment\",\"keyword.operator.comparison\",\"keyword.operator.type\",\"keyword.operator\",\"keyword\",\"punctuation.definition.string\",\"punctuation\",\"variable.other.readwrite.js\",\"storage.type\",\"source.css\",\"string.quoted\"],\"settings\":{\"fontStyle\":\"\"}}],\"styleOverrides\":{\"frames\":{\"editorBackground\":\"var(--sl-color-gray-6)\",\"terminalBackground\":\"var(--sl-color-gray-6)\",\"editorActiveTabBackground\":\"var(--sl-color-gray-6)\",\"terminalTitlebarDotsForeground\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"terminalTitlebarDotsOpacity\":\"0.75\",\"inlineButtonForeground\":\"var(--sl-color-text)\",\"frameBoxShadowCssValue\":\"none\"},\"textMarkers\":{\"markBackground\":\"#ffffff17\",\"markBorderColor\":\"#ffffff40\"}}},{\"name\":\"Night Owl Light\",\"type\":\"light\",\"colors\":{\"focusBorder\":\"#93a1a1\",\"foreground\":\"#403f53\",\"disabledForeground\":\"#61616180\",\"descriptionForeground\":\"#403f53\",\"errorForeground\":\"#403f53\",\"icon.foreground\":\"#424242\",\"contrastActiveBorder\":null,\"contrastBorder\":null,\"textBlockQuote.background\":\"#7f7f7f1a\",\"textBlockQuote.border\":\"#007acc80\",\"textCodeBlock.background\":\"#dcdcdc66\",\"textLink.activeForeground\":\"#006ab1\",\"textLink.foreground\":\"#006ab1\",\"textPreformat.foreground\":\"#a31515\",\"textSeparator.foreground\":\"#0000002e\",\"editor.background\":\"#f6f7f9\",\"editor.foreground\":\"#403f53\",\"editorLineNumber.foreground\":\"#90a7b2\",\"editorLineNumber.activeForeground\":\"#403f53\",\"editorActiveLineNumber.foreground\":\"#0b216f\",\"editor.selectionBackground\":\"#e0e0e0\",\"editor.inactiveSelectionBackground\":\"#e0e0e080\",\"editor.selectionHighlightBackground\":\"#339cec33\",\"editorError.foreground\":\"#e64d49\",\"editorWarning.foreground\":\"#daaa01\",\"editorInfo.foreground\":\"#1a85ff\",\"editorHint.foreground\":\"#6c6c6c\",\"problemsErrorIcon.foreground\":\"#e64d49\",\"problemsWarningIcon.foreground\":\"#daaa01\",\"problemsInfoIcon.foreground\":\"#1a85ff\",\"editor.findMatchBackground\":\"#93a1a16c\",\"editor.findMatchHighlightBackground\":\"#93a1a16c\",\"editor.findRangeHighlightBackground\":\"#7497a633\",\"editorLink.activeForeground\":\"#0000ff\",\"editorLightBulb.foreground\":\"#ddb100\",\"editorLightBulbAutoFix.foreground\":\"#007acc\",\"diffEditor.insertedTextBackground\":\"#9ccc2c40\",\"diffEditor.insertedTextBorder\":null,\"diffEditor.removedTextBackground\":\"#ff000033\",\"diffEditor.removedTextBorder\":null,\"diffEditor.insertedLineBackground\":\"#9bb95533\",\"diffEditor.removedLineBackground\":\"#ff000033\",\"editorStickyScroll.background\":\"#fbfbfb\",\"editorStickyScrollHover.background\":\"#f0f0f0\",\"editorInlayHint.background\":\"#2aa29899\",\"editorInlayHint.foreground\":\"#f0f0f0\",\"editorInlayHint.typeBackground\":\"#2aa29899\",\"editorInlayHint.typeForeground\":\"#f0f0f0\",\"editorInlayHint.parameterBackground\":\"#2aa29899\",\"editorInlayHint.parameterForeground\":\"#f0f0f0\",\"editorPane.background\":\"#fbfbfb\",\"editorGroup.emptyBackground\":null,\"editorGroup.focusedEmptyBorder\":null,\"editorGroupHeader.tabsBackground\":\"var(--sl-color-gray-6)\",\"editorGroupHeader.tabsBorder\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"editorGroupHeader.noTabsBackground\":\"#f0f0f0\",\"editorGroupHeader.border\":null,\"editorGroup.border\":\"#f0f0f0\",\"editorGroup.dropBackground\":\"#2677cb2d\",\"editorGroup.dropIntoPromptForeground\":\"#403f53\",\"editorGroup.dropIntoPromptBackground\":\"#f0f0f0\",\"editorGroup.dropIntoPromptBorder\":null,\"sideBySideEditor.horizontalBorder\":\"#f0f0f0\",\"sideBySideEditor.verticalBorder\":\"#f0f0f0\",\"scrollbar.shadow\":\"#cccccc\",\"scrollbarSlider.background\":\"#0000001a\",\"scrollbarSlider.hoverBackground\":\"#00000055\",\"scrollbarSlider.activeBackground\":\"#00000099\",\"panel.background\":\"#f0f0f0\",\"panel.border\":\"#d9d9d9\",\"panelTitle.activeBorder\":\"#424242\",\"panelTitle.activeForeground\":\"#424242\",\"panelTitle.inactiveForeground\":\"#424242bf\",\"panelSectionHeader.background\":\"#80808051\",\"terminal.background\":\"#f6f6f6\",\"widget.shadow\":\"#d9d9d9\",\"editorWidget.background\":\"#f0f0f0\",\"editorWidget.foreground\":\"#403f53\",\"editorWidget.border\":\"#d9d9d9\",\"quickInput.background\":\"#f0f0f0\",\"quickInput.foreground\":\"#403f53\",\"quickInputTitle.background\":\"#0000000f\",\"pickerGroup.foreground\":\"#403f53\",\"pickerGroup.border\":\"#d9d9d9\",\"editor.hoverHighlightBackground\":\"#339cec33\",\"editorHoverWidget.background\":\"#f0f0f0\",\"editorHoverWidget.foreground\":\"#403f53\",\"editorHoverWidget.border\":\"#d9d9d9\",\"editorHoverWidget.statusBarBackground\":\"#e4e4e4\",\"titleBar.activeBackground\":\"var(--sl-color-gray-6)\",\"titleBar.activeForeground\":\"var(--sl-color-text)\",\"titleBar.inactiveBackground\":\"#f0f0f099\",\"titleBar.inactiveForeground\":\"#33333399\",\"titleBar.border\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"toolbar.hoverBackground\":\"#b8b8b850\",\"toolbar.activeBackground\":\"#a6a6a650\",\"tab.activeBackground\":\"#f6f6f6\",\"tab.unfocusedActiveBackground\":\"#f6f6f6\",\"tab.inactiveBackground\":\"#f0f0f0\",\"tab.unfocusedInactiveBackground\":\"#f0f0f0\",\"tab.activeForeground\":\"var(--sl-color-text)\",\"tab.inactiveForeground\":\"#403f53\",\"tab.unfocusedActiveForeground\":\"#403f53b3\",\"tab.unfocusedInactiveForeground\":\"#403f5380\",\"tab.hoverBackground\":null,\"tab.unfocusedHoverBackground\":null,\"tab.hoverForeground\":null,\"tab.unfocusedHoverForeground\":null,\"tab.border\":\"#f0f0f0\",\"tab.lastPinnedBorder\":\"#a9a9a9\",\"tab.activeBorder\":\"transparent\",\"tab.unfocusedActiveBorder\":null,\"tab.activeBorderTop\":\"var(--sl-color-accent)\",\"tab.unfocusedActiveBorderTop\":null,\"tab.hoverBorder\":null,\"tab.unfocusedHoverBorder\":null,\"tab.activeModifiedBorder\":\"#2aa298\",\"tab.inactiveModifiedBorder\":\"#93a1a1\",\"tab.unfocusedActiveModifiedBorder\":\"#93a1a1\",\"tab.unfocusedInactiveModifiedBorder\":\"#93a1a1\",\"badge.background\":\"#2aa298\",\"badge.foreground\":\"#f0f0f0\",\"button.background\":\"#2aa298\",\"button.foreground\":\"#f0f0f0\",\"button.border\":null,\"button.separator\":\"#f0f0f066\",\"button.hoverBackground\":\"#22827a\",\"button.secondaryBackground\":\"#5f6a79\",\"button.secondaryForeground\":\"#ffffff\",\"button.secondaryHoverBackground\":\"#4c5561\",\"dropdown.background\":\"#f0f0f0\",\"dropdown.foreground\":\"#403f53\",\"dropdown.border\":\"#d9d9d9\",\"list.activeSelectionBackground\":\"#d3e8f8\",\"list.activeSelectionForeground\":\"#403f53\",\"tree.indentGuidesStroke\":\"#a9a9a9\",\"input.background\":\"#f0f0f0\",\"input.foreground\":\"#403f53\",\"input.placeholderForeground\":\"#93a1a1\",\"inputOption.activeBorder\":\"#2aa298\",\"inputOption.hoverBackground\":\"#b8b8b850\",\"inputOption.activeBackground\":\"#93a1a133\",\"inputOption.activeForeground\":\"#000000\",\"inputValidation.infoBackground\":\"#f0f0f0\",\"inputValidation.infoBorder\":\"#d0d0d0\",\"inputValidation.warningBackground\":\"#daaa01\",\"inputValidation.warningBorder\":\"#e0af02\",\"inputValidation.errorBackground\":\"#f76e6e\",\"inputValidation.errorBorder\":\"#de3d3b\",\"keybindingLabel.background\":\"#dddddd66\",\"keybindingLabel.foreground\":\"#555555\",\"keybindingLabel.border\":\"#cccccc66\",\"keybindingLabel.bottomBorder\":\"#bbbbbb66\",\"menu.foreground\":\"#403f53\",\"menu.background\":\"#f0f0f0\",\"menu.selectionForeground\":\"#403f53\",\"menu.selectionBackground\":\"#d3e8f8\",\"menu.separatorBackground\":\"#d4d4d4\",\"editor.snippetTabstopHighlightBackground\":\"#0a326433\",\"editor.snippetFinalTabstopHighlightBorder\":\"#0a326480\",\"terminal.ansiBlack\":\"#403f53\",\"terminal.ansiRed\":\"#de3d3b\",\"terminal.ansiGreen\":\"#08916a\",\"terminal.ansiYellow\":\"#e0af02\",\"terminal.ansiBlue\":\"#288ed7\",\"terminal.ansiMagenta\":\"#d6438a\",\"terminal.ansiCyan\":\"#2aa298\",\"terminal.ansiWhite\":\"#f0f0f0\",\"terminal.ansiBrightBlack\":\"#403f53\",\"terminal.ansiBrightRed\":\"#de3d3b\",\"terminal.ansiBrightGreen\":\"#08916a\",\"terminal.ansiBrightYellow\":\"#daaa01\",\"terminal.ansiBrightBlue\":\"#288ed7\",\"terminal.ansiBrightMagenta\":\"#d6438a\",\"terminal.ansiBrightCyan\":\"#2aa298\",\"terminal.ansiBrightWhite\":\"#f0f0f0\",\"selection.background\":\"#7a8181ad\",\"notifications.background\":\"#f0f0f0\",\"notifications.foreground\":\"#403f53\",\"notificationLink.foreground\":\"#994cc3\",\"notifications.border\":\"#cccccc\",\"notificationCenter.border\":\"#cccccc\",\"notificationToast.border\":\"#cccccc\",\"notificationCenterHeader.foreground\":\"#403f53\",\"notificationCenterHeader.background\":\"#f0f0f0\",\"input.border\":\"#d9d9d9\",\"progressBar.background\":\"#2aa298\",\"list.inactiveSelectionBackground\":\"#e0e7ea\",\"list.inactiveSelectionForeground\":\"#403f53\",\"list.focusBackground\":\"#d3e8f8\",\"list.hoverBackground\":\"#d3e8f8\",\"list.focusForeground\":\"#403f53\",\"list.hoverForeground\":\"#403f53\",\"list.highlightForeground\":\"#403f53\",\"list.errorForeground\":\"#e64d49\",\"list.warningForeground\":\"#daaa01\",\"activityBar.background\":\"#f0f0f0\",\"activityBar.foreground\":\"#403f53\",\"activityBar.dropBackground\":\"#d0d0d0\",\"activityBarBadge.background\":\"#403f53\",\"activityBarBadge.foreground\":\"#f0f0f0\",\"activityBar.border\":\"#f0f0f0\",\"sideBar.background\":\"#f0f0f0\",\"sideBar.foreground\":\"#403f53\",\"sideBarTitle.foreground\":\"#403f53\",\"sideBar.border\":\"#f0f0f0\",\"editorGroup.background\":\"#f6f6f6\",\"editorCursor.foreground\":\"#90a7b2\",\"editor.wordHighlightBackground\":\"#339cec33\",\"editor.wordHighlightStrongBackground\":\"#007dd659\",\"editor.lineHighlightBackground\":\"#f0f0f0\",\"editor.rangeHighlightBackground\":\"#7497a633\",\"editorWhitespace.foreground\":\"#d9d9d9\",\"editorIndentGuide.background\":\"#d9d9d9\",\"editorCodeLens.foreground\":\"#403f53\",\"editorBracketMatch.background\":\"#d3e8f8\",\"editorBracketMatch.border\":\"#2aa298\",\"editorError.border\":\"#fbfbfb\",\"editorWarning.border\":\"#daaa01\",\"editorGutter.addedBackground\":\"#49d0c5\",\"editorGutter.modifiedBackground\":\"#6fbef6\",\"editorGutter.deletedBackground\":\"#f76e6e\",\"editorRuler.foreground\":\"#d9d9d9\",\"editorOverviewRuler.errorForeground\":\"#e64d49\",\"editorOverviewRuler.warningForeground\":\"#daaa01\",\"editorSuggestWidget.background\":\"#f0f0f0\",\"editorSuggestWidget.foreground\":\"#403f53\",\"editorSuggestWidget.highlightForeground\":\"#403f53\",\"editorSuggestWidget.selectedBackground\":\"#d3e8f8\",\"editorSuggestWidget.border\":\"#d9d9d9\",\"debugExceptionWidget.background\":\"#f0f0f0\",\"debugExceptionWidget.border\":\"#d9d9d9\",\"editorMarkerNavigation.background\":\"#d0d0d0\",\"editorMarkerNavigationError.background\":\"#f76e6e\",\"editorMarkerNavigationWarning.background\":\"#daaa01\",\"debugToolBar.background\":\"#f0f0f0\",\"extensionButton.prominentBackground\":\"#2aa298\",\"extensionButton.prominentForeground\":\"#f0f0f0\",\"statusBar.background\":\"#f0f0f0\",\"statusBar.border\":\"#f0f0f0\",\"statusBar.debuggingBackground\":\"#f0f0f0\",\"statusBar.debuggingForeground\":\"#403f53\",\"statusBar.foreground\":\"#403f53\",\"statusBar.noFolderBackground\":\"#f0f0f0\",\"statusBar.noFolderForeground\":\"#403f53\",\"peekView.border\":\"#d9d9d9\",\"peekViewEditor.background\":\"#f6f6f6\",\"peekViewEditorGutter.background\":\"#f6f6f6\",\"peekViewEditor.matchHighlightBackground\":\"#49d0c5\",\"peekViewResult.background\":\"#f0f0f0\",\"peekViewResult.fileForeground\":\"#403f53\",\"peekViewResult.lineForeground\":\"#403f53\",\"peekViewResult.matchHighlightBackground\":\"#49d0c5\",\"peekViewResult.selectionBackground\":\"#e0e7ea\",\"peekViewResult.selectionForeground\":\"#403f53\",\"peekViewTitle.background\":\"#f0f0f0\",\"peekViewTitleLabel.foreground\":\"#403f53\",\"peekViewTitleDescription.foreground\":\"#403f53\",\"terminal.foreground\":\"#403f53\"},\"fg\":\"#403f53\",\"bg\":\"#f6f7f9\",\"semanticHighlighting\":false,\"settings\":[{\"name\":\"Changed\",\"scope\":[\"markup.changed\",\"meta.diff.header.git\",\"meta.diff.header.from-file\",\"meta.diff.header.to-file\"],\"settings\":{\"foreground\":\"#556484\"}},{\"name\":\"Deleted\",\"scope\":[\"markup.deleted.diff\"],\"settings\":{\"foreground\":\"#ae3c3afd\"}},{\"name\":\"Inserted\",\"scope\":[\"markup.inserted.diff\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Global settings\",\"settings\":{\"background\":\"#011627\",\"foreground\":\"#403f53\"}},{\"name\":\"Comment\",\"scope\":[\"comment\"],\"settings\":{\"foreground\":\"#5f636f\"}},{\"name\":\"String\",\"scope\":[\"string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"String Quoted\",\"scope\":[\"string.quoted\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Support Constant Math\",\"scope\":[\"support.constant.math\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Number\",\"scope\":[\"constant.numeric\",\"constant.character.numeric\"],\"settings\":{\"foreground\":\"#aa0982\",\"fontStyle\":\"\"}},{\"name\":\"Built-in constant\",\"scope\":[\"constant.language\",\"punctuation.definition.constant\",\"variable.other.constant\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"User-defined constant\",\"scope\":[\"constant.character\",\"constant.other\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Constant Character Escape\",\"scope\":[\"constant.character.escape\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"RegExp String\",\"scope\":[\"string.regexp\",\"string.regexp keyword.other\"],\"settings\":{\"foreground\":\"#3a688f\"}},{\"name\":\"Comma in functions\",\"scope\":[\"meta.function punctuation.separator.comma\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"Variable\",\"scope\":[\"variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Keyword\",\"scope\":[\"punctuation.accessor\",\"keyword\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage\",\"scope\":[\"storage\",\"meta.var.expr\",\"meta.class meta.method.declaration meta.var.expr storage.type.js\",\"storage.type.property.js\",\"storage.type.property.ts\",\"storage.type.property.tsx\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type.function.arrow.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Class name\",\"scope\":[\"entity.name.class\",\"meta.class entity.name.type.class\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Inherited class\",\"scope\":[\"entity.other.inherited-class\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Function name\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Meta Tag\",\"scope\":[\"punctuation.definition.tag\",\"meta.tag\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"HTML Tag names\",\"scope\":[\"entity.name.tag\",\"meta.tag.other.html\",\"meta.tag.other.js\",\"meta.tag.other.tsx\",\"entity.name.tag.tsx\",\"entity.name.tag.js\",\"entity.name.tag\",\"meta.tag.js\",\"meta.tag.tsx\",\"meta.tag.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Tag attribute\",\"scope\":[\"entity.other.attribute-name\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Entity Name Tag Custom\",\"scope\":[\"entity.name.tag.custom\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Library (function & constant)\",\"scope\":[\"support.function\",\"support.constant\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Support Constant Property Value meta\",\"scope\":[\"support.constant.meta.property-value\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Library class/type\",\"scope\":[\"support.type\",\"support.class\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Support Variable DOM\",\"scope\":[\"support.variable.dom\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Invalid\",\"scope\":[\"invalid\"],\"settings\":{\"foreground\":\"#bb2060\"}},{\"name\":\"Invalid deprecated\",\"scope\":[\"invalid.deprecated\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Keyword Operator\",\"scope\":[\"keyword.operator\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Relational\",\"scope\":[\"keyword.operator.relational\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Assignment\",\"scope\":[\"keyword.operator.assignment\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Arithmetic\",\"scope\":[\"keyword.operator.arithmetic\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Bitwise\",\"scope\":[\"keyword.operator.bitwise\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Increment\",\"scope\":[\"keyword.operator.increment\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Ternary\",\"scope\":[\"keyword.operator.ternary\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Double-Slashed Comment\",\"scope\":[\"comment.line.double-slash\"],\"settings\":{\"foreground\":\"#5d6376\"}},{\"name\":\"Object\",\"scope\":[\"object\"],\"settings\":{\"foreground\":\"#58656a\"}},{\"name\":\"Null\",\"scope\":[\"constant.language.null\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Meta Brace\",\"scope\":[\"meta.brace\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Meta Delimiter Period\",\"scope\":[\"meta.delimiter.period\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Punctuation Definition String\",\"scope\":[\"punctuation.definition.string\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Punctuation Definition String Markdown\",\"scope\":[\"punctuation.definition.string.begin.markdown\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Boolean\",\"scope\":[\"constant.language.boolean\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Object Comma\",\"scope\":[\"object.comma\"],\"settings\":{\"foreground\":\"#646464\"}},{\"name\":\"Variable Parameter Function\",\"scope\":[\"variable.parameter.function\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Support Type Property Name & entity name tags\",\"scope\":[\"support.type.vendor.property-name\",\"support.constant.vendor.property-value\",\"support.type.property-name\",\"meta.property-list entity.name.tag\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Entity Name tag reference in stylesheets\",\"scope\":[\"meta.property-list entity.name.tag.reference\"],\"settings\":{\"foreground\":\"#286d70\"}},{\"name\":\"Constant Other Color RGB Value Punctuation Definition Constant\",\"scope\":[\"constant.other.color.rgb-value punctuation.definition.constant\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Constant Other Color\",\"scope\":[\"constant.other.color\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Keyword Other Unit\",\"scope\":[\"keyword.other.unit\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Meta Selector\",\"scope\":[\"meta.selector\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Entity Other Attribute Name Id\",\"scope\":[\"entity.other.attribute-name.id\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Meta Property Name\",\"scope\":[\"meta.property-name\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Doctypes\",\"scope\":[\"entity.name.tag.doctype\",\"meta.tag.sgml.doctype\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Punctuation Definition Parameters\",\"scope\":[\"punctuation.definition.parameters\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Keyword Control Operator\",\"scope\":[\"keyword.control.operator\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Keyword Operator Logical\",\"scope\":[\"keyword.operator.logical\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"\"}},{\"name\":\"Variable Instances\",\"scope\":[\"variable.instance\",\"variable.other.instance\",\"variable.readwrite.instance\",\"variable.other.readwrite.instance\",\"variable.other.property\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Variable Property Other object property\",\"scope\":[\"variable.other.object.property\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Variable Property Other object\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Entity Name Function\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Keyword Operator Comparison, imports, returns and Keyword Operator Ruby\",\"scope\":[\"keyword.operator.comparison\",\"keyword.control.flow.js\",\"keyword.control.flow.ts\",\"keyword.control.flow.tsx\",\"keyword.control.ruby\",\"keyword.control.module.ruby\",\"keyword.control.class.ruby\",\"keyword.control.def.ruby\",\"keyword.control.loop.js\",\"keyword.control.loop.ts\",\"keyword.control.import.js\",\"keyword.control.import.ts\",\"keyword.control.import.tsx\",\"keyword.control.from.js\",\"keyword.control.from.ts\",\"keyword.control.from.tsx\",\"keyword.operator.instanceof.js\",\"keyword.operator.expression.instanceof.ts\",\"keyword.operator.expression.instanceof.tsx\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Control Conditional\",\"scope\":[\"keyword.control.conditional.js\",\"keyword.control.conditional.ts\",\"keyword.control.switch.js\",\"keyword.control.switch.ts\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"\"}},{\"name\":\"Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords\",\"scope\":[\"support.constant\",\"keyword.other.special-method\",\"keyword.other.new\",\"keyword.other.debugger\",\"keyword.control\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Support Function\",\"scope\":[\"support.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Invalid Broken\",\"scope\":[\"invalid.broken\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Invalid Unimplemented\",\"scope\":[\"invalid.unimplemented\"],\"settings\":{\"foreground\":\"#486e26\"}},{\"name\":\"Invalid Illegal\",\"scope\":[\"invalid.illegal\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Language Variable\",\"scope\":[\"variable.language\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Support Variable Property\",\"scope\":[\"support.variable.property\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Variable Function\",\"scope\":[\"variable.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variable Interpolation\",\"scope\":[\"variable.interpolation\"],\"settings\":{\"foreground\":\"#a64348\"}},{\"name\":\"Meta Function Call\",\"scope\":[\"meta.function-call\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Punctuation Section Embedded\",\"scope\":[\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Punctuation Tweaks\",\"scope\":[\"punctuation.terminator.expression\",\"punctuation.definition.arguments\",\"punctuation.definition.array\",\"punctuation.section.array\",\"meta.array\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"More Punctuation Tweaks\",\"scope\":[\"punctuation.definition.list.begin\",\"punctuation.definition.list.end\",\"punctuation.separator.arguments\",\"punctuation.definition.list\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Template Strings\",\"scope\":[\"string.template meta.template.expression\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Backticks(``) in Template Strings\",\"scope\":[\"string.template punctuation.definition.string\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Italics\",\"scope\":[\"italic\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"italic\"}},{\"name\":\"Bold\",\"scope\":[\"bold\"],\"settings\":{\"foreground\":\"#3b61b0\",\"fontStyle\":\"bold\"}},{\"name\":\"Quote\",\"scope\":[\"quote\"],\"settings\":{\"foreground\":\"#5c6285\"}},{\"name\":\"Raw Code\",\"scope\":[\"raw\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"CoffeeScript Variable Assignment\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#186e73\"}},{\"name\":\"CoffeeScript Parameter Function\",\"scope\":[\"variable.parameter.function.coffee\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"CoffeeScript Assignments\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"C# Readwrite Variables\",\"scope\":[\"variable.other.readwrite.cs\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"C# Classes & Storage types\",\"scope\":[\"entity.name.type.class.cs\",\"storage.type.cs\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"C# Namespaces\",\"scope\":[\"entity.name.type.namespace.cs\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Tag names in Stylesheets\",\"scope\":[\"entity.name.tag.css\",\"entity.name.tag.less\",\"entity.name.tag.custom.css\",\"support.constant.property-value.css\"],\"settings\":{\"foreground\":\"#984e4d\",\"fontStyle\":\"\"}},{\"name\":\"Wildcard(*) selector in Stylesheets\",\"scope\":[\"entity.name.tag.wildcard.css\",\"entity.name.tag.wildcard.less\",\"entity.name.tag.wildcard.scss\",\"entity.name.tag.wildcard.sass\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"CSS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Attribute Name for CSS\",\"scope\":[\"meta.attribute-selector.css entity.other.attribute-name.attribute\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Elixir Classes\",\"scope\":[\"source.elixir support.type.elixir\",\"source.elixir meta.module.elixir entity.name.class.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Functions\",\"scope\":[\"source.elixir entity.name.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Constants\",\"scope\":[\"source.elixir constant.other.symbol.elixir\",\"source.elixir constant.other.keywords.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir String Punctuations\",\"scope\":[\"source.elixir punctuation.definition.string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir\",\"scope\":[\"source.elixir variable.other.readwrite.module.elixir\",\"source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Binary Punctuations\",\"scope\":[\"source.elixir .punctuation.binary.elixir\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Closure Constant Keyword\",\"scope\":[\"constant.keyword.clojure\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Go Function Calls\",\"scope\":[\"source.go meta.function-call.go\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Go Keywords\",\"scope\":[\"source.go keyword.package.go\",\"source.go keyword.import.go\",\"source.go keyword.function.go\",\"source.go keyword.type.go\",\"source.go keyword.struct.go\",\"source.go keyword.interface.go\",\"source.go keyword.const.go\",\"source.go keyword.var.go\",\"source.go keyword.map.go\",\"source.go keyword.channel.go\",\"source.go keyword.control.go\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Go Constants e.g. nil, string format (%s, %d, etc.)\",\"scope\":[\"source.go constant.language.go\",\"source.go constant.other.placeholder.go\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"C++ Functions\",\"scope\":[\"entity.name.function.preprocessor.cpp\",\"entity.scope.name.cpp\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"C++ Meta Namespace\",\"scope\":[\"meta.namespace-block.cpp\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"C++ Language Primitive Storage\",\"scope\":[\"storage.type.language.primitive.cpp\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"C++ Preprocessor Macro\",\"scope\":[\"meta.preprocessor.macro.cpp\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"C++ Variable Parameter\",\"scope\":[\"variable.parameter\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Powershell Variables\",\"scope\":[\"variable.other.readwrite.powershell\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Powershell Function\",\"scope\":[\"support.function.powershell\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"ID Attribute Name in HTML\",\"scope\":[\"entity.other.attribute-name.id.html\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"HTML Punctuation Definition Tag\",\"scope\":[\"punctuation.definition.tag.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"HTML Doctype\",\"scope\":[\"meta.tag.sgml.doctype.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"JavaScript Classes\",\"scope\":[\"meta.class entity.name.type.class.js\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"JavaScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.js\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"JavaScript Terminator\",\"scope\":[\"terminator.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Meta Punctuation Definition\",\"scope\":[\"meta.js punctuation.definition.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Entity Names in Code Documentations\",\"scope\":[\"entity.name.type.instance.jsdoc\",\"entity.name.type.instance.phpdoc\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"Other Variables in Code Documentations\",\"scope\":[\"variable.other.jsdoc\",\"variable.other.phpdoc\"],\"settings\":{\"foreground\":\"#3e697c\"}},{\"name\":\"JavaScript module imports and exports\",\"scope\":[\"variable.other.meta.import.js\",\"meta.import.js variable.other\",\"variable.other.meta.export.js\",\"meta.export.js variable.other\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Variable Parameter Function\",\"scope\":[\"variable.parameter.function.js\"],\"settings\":{\"foreground\":\"#555ea2\"}},{\"name\":\"JavaScript[React] Variable Other Object\",\"scope\":[\"variable.other.object.js\",\"variable.other.object.jsx\",\"variable.object.property.js\",\"variable.object.property.jsx\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Variables\",\"scope\":[\"variable.js\",\"variable.other.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Entity Name Type\",\"scope\":[\"entity.name.type.js\",\"entity.name.type.module.js\"],\"settings\":{\"foreground\":\"#111111\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Support Classes\",\"scope\":[\"support.class.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JSON Property Names\",\"scope\":[\"support.type.property-name.json\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"JSON Support Constants\",\"scope\":[\"support.constant.json\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"JSON Property values (string)\",\"scope\":[\"meta.structure.dictionary.value.json string.quoted.double\"],\"settings\":{\"foreground\":\"#7c5686\"}},{\"name\":\"Strings in JSON values\",\"scope\":[\"string.quoted.double.json punctuation.definition.string.json\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Specific JSON Property values like null\",\"scope\":[\"meta.structure.dictionary.json meta.structure.dictionary.value constant.language\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"JavaScript Other Variable\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Ruby Variables\",\"scope\":[\"variable.other.ruby\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Ruby Class\",\"scope\":[\"entity.name.type.class.ruby\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Ruby Hashkeys\",\"scope\":[\"constant.language.symbol.hashkey.ruby\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Ruby Symbols\",\"scope\":[\"constant.language.symbol.ruby\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"LESS Tag names\",\"scope\":[\"entity.name.tag.less\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"LESS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Attribute Name for LESS\",\"scope\":[\"meta.attribute-selector.less entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Markdown Headings\",\"scope\":[\"markup.heading.markdown\",\"markup.heading.setext.1.markdown\",\"markup.heading.setext.2.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown Italics\",\"scope\":[\"markup.italic.markdown\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"italic\"}},{\"name\":\"Markdown Bold\",\"scope\":[\"markup.bold.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\",\"fontStyle\":\"bold\"}},{\"name\":\"Markdown Quote + others\",\"scope\":[\"markup.quote.markdown\"],\"settings\":{\"foreground\":\"#5c6285\"}},{\"name\":\"Markdown Raw Code + others\",\"scope\":[\"markup.inline.raw.markdown\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Markdown Links\",\"scope\":[\"markup.underline.link.markdown\",\"markup.underline.link.image.markdown\"],\"settings\":{\"foreground\":\"#954f5a\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Link Title and Description\",\"scope\":[\"string.other.link.title.markdown\",\"string.other.link.description.markdown\"],\"settings\":{\"foreground\":\"#403f53\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Punctuation\",\"scope\":[\"punctuation.definition.string.markdown\",\"punctuation.definition.string.begin.markdown\",\"punctuation.definition.string.end.markdown\",\"meta.link.inline.markdown punctuation.definition.string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown MetaData Punctuation\",\"scope\":[\"punctuation.definition.metadata.markdown\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Markdown List Punctuation\",\"scope\":[\"beginning.punctuation.definition.list.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown Inline Raw String\",\"scope\":[\"markup.inline.raw.string.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"PHP Variables\",\"scope\":[\"variable.other.php\",\"variable.other.property.php\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Support Classes in PHP\",\"scope\":[\"support.class.php\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Punctuations in PHP function calls\",\"scope\":[\"meta.function-call.php punctuation\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"PHP Global Variables\",\"scope\":[\"variable.other.global.php\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Declaration Punctuation in PHP Global Variables\",\"scope\":[\"variable.other.global.php punctuation.definition.variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Language Constants in Python\",\"scope\":[\"constant.language.python\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Python Function Parameter and Arguments\",\"scope\":[\"variable.parameter.function.python\",\"meta.function-call.arguments.python\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Python Function Call\",\"scope\":[\"meta.function-call.python\",\"meta.function-call.generic.python\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Punctuations in Python\",\"scope\":[\"punctuation.python\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Decorator Functions in Python\",\"scope\":[\"entity.name.function.decorator.python\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Python Language Variable\",\"scope\":[\"source.python variable.language.special\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Python import control keyword\",\"scope\":[\"keyword.control\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"SCSS Variable\",\"scope\":[\"variable.scss\",\"variable.sass\",\"variable.parameter.url.scss\",\"variable.parameter.url.sass\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Attribute Name for SASS\",\"scope\":[\"meta.attribute-selector.scss entity.other.attribute-name.attribute\",\"meta.attribute-selector.sass entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Tag names in SASS\",\"scope\":[\"entity.name.tag.scss\",\"entity.name.tag.sass\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"SASS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.scss\",\"keyword.other.unit.sass\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"TypeScript[React] Variables and Object Properties\",\"scope\":[\"variable.other.readwrite.alias.ts\",\"variable.other.readwrite.alias.tsx\",\"variable.other.readwrite.ts\",\"variable.other.readwrite.tsx\",\"variable.other.object.ts\",\"variable.other.object.tsx\",\"variable.object.property.ts\",\"variable.object.property.tsx\",\"variable.other.ts\",\"variable.other.tsx\",\"variable.tsx\",\"variable.ts\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript[React] Entity Name Types\",\"scope\":[\"entity.name.type.ts\",\"entity.name.type.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript[React] Node Classes\",\"scope\":[\"support.class.node.ts\",\"support.class.node.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"TypeScript[React] Entity Name Types as Parameters\",\"scope\":[\"meta.type.parameters.ts entity.name.type\",\"meta.type.parameters.tsx entity.name.type\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"TypeScript[React] Import/Export Punctuations\",\"scope\":[\"meta.import.ts punctuation.definition.block\",\"meta.import.tsx punctuation.definition.block\",\"meta.export.ts punctuation.definition.block\",\"meta.export.tsx punctuation.definition.block\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.decorator punctuation.decorator.ts\",\"meta.decorator punctuation.decorator.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.tag.js meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"YAML Entity Name Tags\",\"scope\":[\"entity.name.tag.yaml\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"JavaScript Variable Other ReadWrite\",\"scope\":[\"variable.other.readwrite.js\",\"variable.parameter\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Support Class Component\",\"scope\":[\"support.class.component.js\",\"support.class.component.tsx\"],\"settings\":{\"foreground\":\"#aa0982\",\"fontStyle\":\"\"}},{\"name\":\"Text nested in React tags\",\"scope\":[\"meta.jsx.children\",\"meta.jsx.children.js\",\"meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript Classes\",\"scope\":[\"meta.class entity.name.type.class.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript Entity Name Type\",\"scope\":[\"entity.name.type.tsx\",\"entity.name.type.module.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript Class Variable Keyword\",\"scope\":[\"meta.class.ts meta.var.expr.ts storage.type.ts\",\"meta.class.tsx meta.var.expr.tsx storage.type.tsx\"],\"settings\":{\"foreground\":\"#76578b\"}},{\"name\":\"TypeScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.ts\",\"meta.method.declaration storage.type.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"normalize font style of certain components\",\"scope\":[\"meta.property-list.css meta.property-value.css variable.other.less\",\"meta.property-list.scss variable.scss\",\"meta.property-list.sass variable.sass\",\"meta.brace\",\"keyword.operator.operator\",\"keyword.operator.or.regexp\",\"keyword.operator.expression.in\",\"keyword.operator.relational\",\"keyword.operator.assignment\",\"keyword.operator.comparison\",\"keyword.operator.type\",\"keyword.operator\",\"keyword\",\"punctuation.definition.string\",\"punctuation\",\"variable.other.readwrite.js\",\"storage.type\",\"source.css\",\"string.quoted\"],\"settings\":{\"fontStyle\":\"\"}}],\"styleOverrides\":{\"frames\":{\"editorBackground\":\"var(--sl-color-gray-7)\",\"terminalBackground\":\"var(--sl-color-gray-7)\",\"editorActiveTabBackground\":\"var(--sl-color-gray-7)\",\"terminalTitlebarDotsForeground\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"terminalTitlebarDotsOpacity\":\"0.75\",\"inlineButtonForeground\":\"var(--sl-color-text)\",\"frameBoxShadowCssValue\":\"none\"},\"textMarkers\":{\"markBackground\":\"#0000001a\",\"markBorderColor\":\"#00000055\"}}}],\"defaultLocale\":\"en\",\"cascadeLayer\":\"starlight.components\",\"styleOverrides\":{\"borderRadius\":\"0px\",\"borderWidth\":\"1px\",\"codePaddingBlock\":\"0.75rem\",\"codePaddingInline\":\"1rem\",\"codeFontFamily\":\"var(--__sl-font-mono)\",\"codeFontSize\":\"var(--sl-text-code)\",\"codeLineHeight\":\"var(--sl-line-height)\",\"uiFontFamily\":\"var(--__sl-font)\",\"textMarkers\":{\"lineDiffIndicatorMarginLeft\":\"0.25rem\",\"defaultChroma\":\"45\",\"backgroundOpacity\":\"60%\"}},\"plugins\":[{\"name\":\"Starlight Plugin\",\"hooks\":{}},{\"name\":\"astro-expressive-code\",\"hooks\":{}}]}]],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true,\"allowedDomains\":[],\"actionBodySizeLimit\":1048576},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"headingIdCompat\":false,\"preserveScriptOrder\":false,\"liveContentCollections\":false,\"csp\":false,\"staticImportMetaEnv\":false,\"chromeDevtoolsWorkspace\":false,\"failOnPrerenderConflict\":false,\"svgo\":false},\"legacy\":{\"collections\":false},\"prefetch\":{\"prefetchAll\":true},\"i18n\":{\"defaultLocale\":\"en\",\"locales\":[\"en\"],\"routing\":{\"prefixDefaultLocale\":false,\"redirectToDefaultLocale\":false,\"fallbackType\":\"redirect\"}}}","docs",["Map",11,12,26,27,46,47,65,66,88,89,107,108,126,127,148,149],"index",{"id":11,"data":13,"filePath":24,"digest":25,"deferredRender":16},{"title":14,"description":15,"editUrl":16,"head":17,"template":18,"hero":19,"sidebar":21,"pagefind":16,"draft":22},"Vonage Voice API Workshop","Let's build some sample applications!",true,[],"splash",{"tagline":15,"actions":20},[],{"hidden":22,"attrs":23},false,{},"src/content/docs/index.mdx","46148d68185c9a1e","02_setup_application",{"id":26,"data":28,"body":35,"filePath":36,"digest":37,"rendered":38},{"title":29,"description":30,"editUrl":16,"head":31,"template":32,"sidebar":33,"pagefind":16,"draft":22},"Setup Application","Create an application.",[],"doc",{"hidden":22,"attrs":34},{},"> Note: Please make sure to redeem the coupon code to your Vonage account's \u003Ca href=\"https://dashboard.vonage.com/coupons\" target=\"_blank\">dashboard\u003C/a> before continuing. It is needed to purchase a phone number.\n\nIn the terminal below, you should see a set up script running asking for your `API key`. Complete the steps in the set up script. This will create an Application with Voice functionality, purchase a phone number, and create the needed Webhook endpoints.\n\n> Note: You can get your credentials in the \u003Ca href=\"https://dashboard.vonage.com/settings\" target=\"_blank\">Vonage dashboard Settings Page\u003C/a>\n\nIf successful, you should see `APPLICATION READY` with a URL. Click the link to open in a new window or tab.","src/content/docs/02_Setup_Application.md","41ac2dedeb3ab62b",{"html":39,"metadata":40},"\u003Cblockquote>\n\u003Cp>Note: Please make sure to redeem the coupon code to your Vonage account’s \u003Ca href=\"https://dashboard.vonage.com/coupons\" target=\"_blank\">dashboard\u003C/a> before continuing. It is needed to purchase a phone number.\u003C/p>\n\u003C/blockquote>\n\u003Cp>In the terminal below, you should see a set up script running asking for your \u003Ccode dir=\"auto\">API key\u003C/code>. Complete the steps in the set up script. This will create an Application with Voice functionality, purchase a phone number, and create the needed Webhook endpoints.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Note: You can get your credentials in the \u003Ca href=\"https://dashboard.vonage.com/settings\" target=\"_blank\">Vonage dashboard Settings Page\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cp>If successful, you should see \u003Ccode dir=\"auto\">APPLICATION READY\u003C/code> with a URL. Click the link to open in a new window or tab.\u003C/p>",{"headings":41,"localImagePaths":42,"remoteImagePaths":43,"frontmatter":44,"imagePaths":45},[],[],[],{"title":29,"description":30},[],"01_create_account",{"id":46,"data":48,"body":54,"filePath":55,"digest":56,"rendered":57},{"title":49,"description":50,"editUrl":16,"head":51,"template":32,"sidebar":52,"pagefind":16,"draft":22},"Create an Account","Create a Vonage account.",[],{"hidden":22,"attrs":53},{},"First, a Vonage account is needed to get the credentials to set up this workshop applications. You can sign up for your account here: \u003Ca href=\"https://dashboard.vonage.com\" target=\"_blank\">Vonage dashboard\u003C/a>\n\nHere's a coupon to add money to your account:\n\nIf your account is in US dollars:\n\n```html\nTorcWebUS2026\n```\n\nIf your account is in Euros:\n\n```html\nTorcWebEUR2026\n```\n\n> Note: Make sure to copy your API Key and API Secret somewhere. We will need it in the next step.","src/content/docs/01_Create_Account.md","0434ab7976c6a491",{"html":58,"metadata":59},"\u003Cp>First, a Vonage account is needed to get the credentials to set up this workshop applications. You can sign up for your account here: \u003Ca href=\"https://dashboard.vonage.com\" target=\"_blank\">Vonage dashboard\u003C/a>\u003C/p>\n\u003Cp>Here’s a coupon to add money to your account:\u003C/p>\n\u003Cp>If your account is in US dollars:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">TorcWebUS2026\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"TorcWebUS2026\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>If your account is in Euros:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">TorcWebEUR2026\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"TorcWebEUR2026\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Note: Make sure to copy your API Key and API Secret somewhere. We will need it in the next step.\u003C/p>\n\u003C/blockquote>",{"headings":60,"localImagePaths":61,"remoteImagePaths":62,"frontmatter":63,"imagePaths":64},[],[],[],{"title":49,"description":50},[],"03_add_client_sdk",{"id":65,"data":67,"body":73,"filePath":74,"digest":75,"rendered":76},{"title":68,"description":69,"editUrl":16,"head":70,"template":32,"sidebar":71,"pagefind":16,"draft":22},"Add Client SDK","Add Vonage Client SDK to index.html",[],{"hidden":22,"attrs":72},{},"We'll be creating a WebXR application using \u003Ca href=\"https://xrblocks.github.io\" target=\"_blank\">XR Blocks\u003C/a> that can answer phone calls.\n\nThe following code will be placed in the `index.html` file.\n\nFirst, we will need to load the Vonage Client SDK from a CDN (`\u003C!-- ⌄⌄⌄ Load the Vonage Client SDK ⌄⌄⌄ -->`):\n```html\n\u003Cscript src=\"https://cdn.jsdelivr.net/npm/@vonage/client-sdk@latest/dist/vonageClientSDK.min.js\">\u003C/script>\n```\n\n> Note: You can also install the Client SDK and point to the nodes module folder if you are using a bundler.\n\n## That's it for the HTML!\n\nEverything else will be handled by XR Blocks.","src/content/docs/03_Add_Client_SDK.md","77c79f191f661eb3",{"html":77,"metadata":78},"\u003Cp>We’ll be creating a WebXR application using \u003Ca href=\"https://xrblocks.github.io\" target=\"_blank\">XR Blocks\u003C/a> that can answer phone calls.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">index.html\u003C/code> file.\u003C/p>\n\u003Cp>First, we will need to load the Vonage Client SDK from a CDN (\u003Ccode dir=\"auto\"><!-- ⌄⌄⌄ Load the Vonage Client SDK ⌄⌄⌄ -->\u003C/code>):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">script\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">src\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://cdn.jsdelivr.net/npm/@vonage/client-sdk@latest/dist/vonageClientSDK.min.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\">></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">script\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript src="https://cdn.jsdelivr.net/npm/@vonage/client-sdk@latest/dist/vonageClientSDK.min.js">\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Note: You can also install the Client SDK and point to the nodes module folder if you are using a bundler.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"thats-it-for-the-html\">That’s it for the HTML!\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#thats-it-for-the-html\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “That’s it for the HTML!”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Everything else will be handled by XR Blocks.\u003C/p>",{"headings":79,"localImagePaths":84,"remoteImagePaths":85,"frontmatter":86,"imagePaths":87},[80],{"depth":81,"slug":82,"text":83},2,"thats-it-for-the-html","That’s it for the HTML!",[],[],{"title":68,"description":69},[],"04_vonage_call_panel",{"id":88,"data":90,"body":96,"filePath":97,"digest":98,"rendered":99},{"title":91,"description":92,"editUrl":16,"head":93,"template":32,"sidebar":94,"pagefind":16,"draft":22},"Vonage Call Panel","Create XR Blocks UI to answer phone calls",[],{"hidden":22,"attrs":95},{},"We'll be creating the UI to recieve phone calls via the Vonage Voice API using the XR Blocks library's \u003Ca href=\"https://xrblocks.github.io/docs/api/classes/SpatialPanel/\" target=\"_blank\">SpatialPanel Class\u003C/a>.\n\nThe following code will be placed in the `VonageAudioCall.js` file.\n\nFirst, let's initiate the constructor for our panel with some variables:\n`// ⌄⌄⌄ Create constructor ⌄⌄⌄`\n```js\nconstructor() {\n super();\n this.token = '';\n this.client = new vonageClientSDK.VonageClient();\n this.callId = null;\n // Keep a reference to the panel so we can destroy it later\n this.panel = null; \n this.statusText = null;\n this.userName = \"XR_User_1\";\n this.grid = null;\n this.controlRow = null;\n}\n```\n\nHere's the function to create the panel:\n`// ⌄⌄⌄ Create call panel ⌄⌄⌄`\n```js\ncreateCallPanel(callerName) {\n // SAFETY: If a panel already exists, don't create another one.\n if (this.panel) return;\n\n console.log(\"Creating Call UI...\");\n \n // 1. Create the Panel\n this.panel = new xb.SpatialPanel({ backgroundColor: '#2b2b2baa' });\n this.panel.position.set(\n 0,\n xb.user.height - 0.5,\n -xb.user.objectDistance\n );\n\n this.add(this.panel);\n\n this.grid = this.panel.addGrid();\n\n // 2. Status Text\n this.statusText = this.grid.addRow({ weight: 0.7 }).addText({\n text: `Incoming call from ${callerName}...`,\n fontColor: '#ffffff',\n fontSize: 0.08,\n });\n\n this.updateControlRow('INCOMING');\n}\n```\n\nFunction to update the call control section:\n`// ⌄⌄⌄ Update call controls ⌄⌄⌄`\n```js\nupdateControlRow(state) {\n if (!this.grid) return;\n\n // 1. Remove the existing row if it exists\n if (this.controlRow) {\n this.grid.remove(this.controlRow);\n this.controlRow = null;\n this.grid.resetLayout();\n }\n\n // 2. Create a fresh row. It will naturally append below the Status Text.\n // We give it the full remaining weight (0.3 relative to the panel, or flexible)\n this.controlRow = this.grid.addRow({ weight: 0.3 });\n\n if (state === 'INCOMING') {\n // --- ANSWER BUTTON ---\n const answerBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({\n text: 'call',\n fontSize: 0.5,\n backgroundColor: '#00ff00'\n });\n answerBtn.onTriggered = () => this._onAnswer();\n\n // --- REJECT BUTTON ---\n const rejectBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({\n text: 'call_end',\n fontSize: 0.5,\n backgroundColor: '#ff0000'\n });\n rejectBtn.onTriggered = () => this._onReject();\n\n } else if (state === 'CONNECTED') {\n // --- HANGUP BUTTON ---\n // This is a fresh row, so layouts will calculate correctly\n const hangupBtn = this.controlRow.addCol({ weight: 1 }).addIconButton({\n text: 'call_end',\n fontSize: 0.5,\n backgroundColor: '#ff0000'\n });\n hangupBtn.onTriggered = () => this._onHangup();\n }\n\n // 3. Force layout update\n this.panel.updateLayouts();\n}\n```\n\nThis function will remove the panel once the call is over:\n`// ⌄⌄⌄ Remove call panel ⌄⌄⌄`\n```js\nremoveCallPanel() {\n if (this.panel) {\n console.log(\"Destroying Call UI...\");\n this.remove(this.panel);\n this.panel = null;\n this.grid = null;\n this.statusText = null;\n this.controlRow = null;\n }\n}\n```\n\nThis function answers the call and updates the status and call control section:\n`// ⌄⌄⌄ Answer call method ⌄⌄⌄`\n```js\n_onAnswer() {\n console.log('Answering...');\n this.client.answer(this.callId)\n .then(() => {\n console.log(\"Success answering call.\");\n this.statusText.text = `Call answered.`;\n this.updateControlRow('CONNECTED');\n })\n .catch(error => {\n console.error(\"Error answering call: \", error);\n }); \n}\n```\n\nThis function will reject the incoming call and remove the panel:\n`// ⌄⌄⌄ Reject call method ⌄⌄⌄`\n```js\n_onReject() {\n console.log('Rejecting...');\n this.client.reject(this.callId)\n .then(() => {\n console.log(\"Success rejecting call.\");\n })\n .catch(error => {\n console.error(\"Error rejecting call: \", error);\n }); \n // We manually destroy the panel here too, just in case the event lags\n this.removeCallPanel(); \n}\n```\n\nThis function will hang up the ongoing call and remove the panel:\n`// ⌄⌄⌄ Hang Up call method ⌄⌄⌄ `\n```js\n_onHangup() {\n console.log('Hanging up...');\n this.client.hangup(this.callId)\n .then(() => {\n console.log(\"Success hanging up call.\");\n })\n .catch(error => {\n console.error(\"Error hanging up call: \", error);\n }); \n // We manually destroy the panel here too, just in case the event lags\n this.removeCallPanel(); \n}\n```\n\nSet up some listeners for the events that the Vonage Client SDK will emit and what to do:\n`// ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄`\n```js\nsetupVonageListeners() {\n // --- CREATE UI ON INVITE ---\n this.client.on('callInvite', (callId, from, channelType) => {\n this.callId = callId;\n const maskedNumber = from.replace(/\\d(?=(?:\\D*\\d){4})/g, \"*\")\n console.log(`Incoming call from ${maskedNumber}`);\n \n // Trigger the UI creation here\n this.createCallPanel(maskedNumber);\n });\n\n this.client.on('legStatusUpdate', (callId, legId, status) => {\n console.log(\"status: \", status);\n if (this.statusText) {\n this.statusText.text = `Status: ${status}`;\n }\n });\n\n // --- REMOVE UI ON CANCEL/HANGUP ---\n this.client.on('callInviteCancel', (callId) => {\n console.log(`Call cancelled: ${callId}`);\n this.callId = null;\n this.removeCallPanel();\n });\n\n this.client.on(\"callHangup\", (callId, callQuality, reason) => {\n console.log(`Call hung up: ${reason}`);\n this.callId = null;\n this.removeCallPanel();\n });\n}\n```\n\nGet a token from the server so you can connect to a session:\n`// ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ `\n```js\nasync connectToVonage(name) {\n try {\n console.log(`Fetching token for ${name}...`);\n\n // 1. Fetch the token (AWAIT the result)\n const response = await fetch(`/token?name=${name}`);\n \n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data = await response.json();\n this.token = data.token;\n console.log(\"Fetched token successfully.\");\n\n // 2. Create the Session (AWAIT the result)\n const sessionId = await this.client.createSession(this.token);\n \n console.log(\"Session created successfully. Session ID:\", sessionId);\n\n // 3. Update UI\n // Instead, update your XR Panel text to show we are ready\n if(this.statusText) {\n this.statusText.text = \"Connected. Waiting for calls...\";\n }\n\n } catch (error) {\n console.error(\"Connection failed:\", error);\n if(this.statusText) this.statusText.text = \"Connection Failed.\";\n }\n}\n```\n\nInitialize the Class when loaded into the page:\n`// ⌄⌄⌄ Initialize ⌄⌄⌄`\n```js\ninit() {\n console.log(\"Vonage init!\",this.client);\n this.setupVonageListeners();\n this.connectToVonage(this.userName);\n}\n```","src/content/docs/04_Vonage_Call_Panel.md","b1135949c5400620",{"html":100,"metadata":101},"\u003Cp>We’ll be creating the UI to recieve phone calls via the Vonage Voice API using the XR Blocks library’s \u003Ca href=\"https://xrblocks.github.io/docs/api/classes/SpatialPanel/\" target=\"_blank\">SpatialPanel Class\u003C/a>.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">VonageAudioCall.js\u003C/code> file.\u003C/p>\n\u003Cp>First, let’s initiate the constructor for our panel with some variables:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create constructor ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">constructor\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">super\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">vonageClientSDK\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">VonageClient\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Keep a reference to the panel so we can destroy it later\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">userName\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">XR_User_1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"constructor() { super(); this.token = ''; this.client = new vonageClientSDK.VonageClient(); this.callId = null; // Keep a reference to the panel so we can destroy it later this.panel = null; this.statusText = null; this.userName = "XR_User_1"; this.grid = null; this.controlRow = null;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Here’s the function to create the panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create call panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createCallPanel\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">callerName\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// SAFETY: If a panel already exists, don't create another one.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Creating Call UI...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Create the Panel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">SpatialPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#2b2b2baa\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">objectDistance\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addGrid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Status Text\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.7\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Incoming call from \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">callerName\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ffffff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.08\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateControlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">INCOMING\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"createCallPanel(callerName) { // SAFETY: If a panel already exists, don't create another one. if (this.panel) return; console.log("Creating Call UI..."); // 1. Create the Panel this.panel = new xb.SpatialPanel({ backgroundColor: '#2b2b2baa' }); this.panel.position.set( 0, xb.user.height - 0.5, -xb.user.objectDistance ); this.add(this.panel); this.grid = this.panel.addGrid(); // 2. Status Text this.statusText = this.grid.addRow({ weight: 0.7 }).addText({ text: `Incoming call from ${callerName}...`, fontColor: '#ffffff', fontSize: 0.08, }); this.updateControlRow('INCOMING');}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Function to update the call control section:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Update call controls ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateControlRow\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">state\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Remove the existing row if it exists\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">resetLayout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Create a fresh row. It will naturally append below the Status Text.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// We give it the full remaining weight (0.3 relative to the panel, or flexible)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.3\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">state\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">INCOMING\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- ANSWER BUTTON ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">answerBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">controlRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">call\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#00ff00\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">answerBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onAnswer\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- REJECT BUTTON ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">rejectBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">controlRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">call_end\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ff0000\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">rejectBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onReject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">else\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">state\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">CONNECTED\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- HANGUP BUTTON ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// This is a fresh row, so layouts will calculate correctly\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hangupBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">controlRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">call_end\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ff0000\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">hangupBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onHangup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 3. Force layout update\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateLayouts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"updateControlRow(state) { if (!this.grid) return; // 1. Remove the existing row if it exists if (this.controlRow) { this.grid.remove(this.controlRow); this.controlRow = null; this.grid.resetLayout(); } // 2. Create a fresh row. It will naturally append below the Status Text. // We give it the full remaining weight (0.3 relative to the panel, or flexible) this.controlRow = this.grid.addRow({ weight: 0.3 }); if (state === 'INCOMING') { // --- ANSWER BUTTON --- const answerBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({ text: 'call', fontSize: 0.5, backgroundColor: '#00ff00' }); answerBtn.onTriggered = () => this._onAnswer(); // --- REJECT BUTTON --- const rejectBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({ text: 'call_end', fontSize: 0.5, backgroundColor: '#ff0000' }); rejectBtn.onTriggered = () => this._onReject(); } else if (state === 'CONNECTED') { // --- HANGUP BUTTON --- // This is a fresh row, so layouts will calculate correctly const hangupBtn = this.controlRow.addCol({ weight: 1 }).addIconButton({ text: 'call_end', fontSize: 0.5, backgroundColor: '#ff0000' }); hangupBtn.onTriggered = () => this._onHangup(); } // 3. Force layout update this.panel.updateLayouts();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will remove the panel once the call is over:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Remove call panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Destroying Call UI...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"removeCallPanel() { if (this.panel) { console.log("Destroying Call UI..."); this.remove(this.panel); this.panel = null; this.grid = null; this.statusText = null; this.controlRow = null; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function answers the call and updates the status and call control section:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Answer call method ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onAnswer\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Answering...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">answer\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Success answering call.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Call answered.\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateControlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">CONNECTED\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Error answering call: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_onAnswer() { console.log('Answering...'); this.client.answer(this.callId) .then(() => { console.log("Success answering call."); this.statusText.text = `Call answered.`; this.updateControlRow('CONNECTED'); }) .catch(error => { console.error("Error answering call: ", error); });}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will reject the incoming call and remove the panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Reject call method ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onReject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Rejecting...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">reject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Success rejecting call.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Error rejecting call: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// We manually destroy the panel here too, just in case the event lags\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_onReject() { console.log('Rejecting...'); this.client.reject(this.callId) .then(() => { console.log("Success rejecting call."); }) .catch(error => { console.error("Error rejecting call: ", error); }); // We manually destroy the panel here too, just in case the event lags this.removeCallPanel();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will hang up the ongoing call and remove the panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Hang Up call method ⌄⌄⌄ \u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onHangup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Hanging up...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hangup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Success hanging up call.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Error hanging up call: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// We manually destroy the panel here too, just in case the event lags\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_onHangup() { console.log('Hanging up...'); this.client.hangup(this.callId) .then(() => { console.log("Success hanging up call."); }) .catch(error => { console.error("Error hanging up call: ", error); }); // We manually destroy the panel here too, just in case the event lags this.removeCallPanel();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Set up some listeners for the events that the Vonage Client SDK will emit and what to do:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setupVonageListeners\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- CREATE UI ON INVITE ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">callInvite\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">channelType\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">;\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">maskedNumber\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">from\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">replace\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">/\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">\\d\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">(?=(?:\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">\\D\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">\\d\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">{4}\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">)\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">/\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">g\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">*\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Incoming call from \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">maskedNumber\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Trigger the UI creation here\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createCallPanel\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">maskedNumber\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">legStatusUpdate\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">legId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">status\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">status: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">status\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Status: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">status\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- REMOVE UI ON CANCEL/HANGUP ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">callInviteCancel\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">callId\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Call cancelled: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">callId\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">callHangup\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">callQuality\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">reason\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Call hung up: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">reason\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"setupVonageListeners() { // --- CREATE UI ON INVITE --- this.client.on('callInvite', (callId, from, channelType) => { this.callId = callId; const maskedNumber = from.replace(/\\d(?=(?:\\D*\\d){4})/g, "*") console.log(`Incoming call from ${maskedNumber}`); // Trigger the UI creation here this.createCallPanel(maskedNumber); }); this.client.on('legStatusUpdate', (callId, legId, status) => { console.log("status: ", status); if (this.statusText) { this.statusText.text = `Status: ${status}`; } }); // --- REMOVE UI ON CANCEL/HANGUP --- this.client.on('callInviteCancel', (callId) => { console.log(`Call cancelled: ${callId}`); this.callId = null; this.removeCallPanel(); }); this.client.on("callHangup", (callId, callQuality, reason) => { console.log(`Call hung up: ${reason}`); this.callId = null; this.removeCallPanel(); });}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Get a token from the server so you can connect to a session:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ \u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">async\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">connectToVonage\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">name\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">try\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Fetching token for \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">name\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Fetch the token (AWAIT the result)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fetch\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">/token?name=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">name\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">ok\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">throw\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">HTTP error! status: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">status\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">json\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Fetched token successfully.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Create the Session (AWAIT the result)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sessionId\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createSession\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Session created successfully. Session ID:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">sessionId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 3. Update UI\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Instead, update your XR Panel text to show we are ready\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Connected. Waiting for calls...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Connection failed:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Connection Failed.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"async connectToVonage(name) { try { console.log(`Fetching token for ${name}...`); // 1. Fetch the token (AWAIT the result) const response = await fetch(`/token?name=${name}`); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); this.token = data.token; console.log("Fetched token successfully."); // 2. Create the Session (AWAIT the result) const sessionId = await this.client.createSession(this.token); console.log("Session created successfully. Session ID:", sessionId); // 3. Update UI // Instead, update your XR Panel text to show we are ready if(this.statusText) { this.statusText.text = "Connected. Waiting for calls..."; } } catch (error) { console.error("Connection failed:", error); if(this.statusText) this.statusText.text = "Connection Failed."; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Initialize the Class when loaded into the page:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Initialize ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">init\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Vonage init!\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setupVonageListeners\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">connectToVonage\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">userName\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"init() { console.log("Vonage init!",this.client); this.setupVonageListeners(); this.connectToVonage(this.userName);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":102,"localImagePaths":103,"remoteImagePaths":104,"frontmatter":105,"imagePaths":106},[],[],[],{"title":91,"description":92},[],"05_exit_button",{"id":107,"data":109,"body":115,"filePath":116,"digest":117,"rendered":118},{"title":110,"description":111,"editUrl":16,"head":112,"template":32,"sidebar":113,"pagefind":16,"draft":22},"Exiting WebXR application","Button to exit WebXR application",[],{"hidden":22,"attrs":114},{},"When in the WebXR environment using a headset, I could not figure out how to leave the experience, so I made an Exit Demo Panel.\n\nThe following code will be placed in the `ExitButton.js` file.\n\nCreate the constructor for the Class:\n`// ⌄⌄⌄ Create constructor ⌄⌄⌄`\n```js\n constructor() {\n super();\n // Keep a reference to the panel so we can destroy it later\n this.panel = null; \n this.statusText = null;\n this.exitPanelText = \"Exit Demo\";\n }\n```\n\nFunction to create a panel for the Exit Button:\n`// ⌄⌄⌄ Create Exit Button panel ⌄⌄⌄`\n```js\n createExitPanel() {\n // SAFETY: If a panel already exists, don't create another one.\n if (this.panel) return;\n\n console.log(\"Creating Exit Button...\");\n \n // 1. Create the Panel\n this.panel = new xb.SpatialPanel({\n width: 0.5,\n height: 0.5, \n backgroundColor: '#2b2b2baa'\n });\n\n this.panel.position.set(\n 0,\n xb.user.height,\n 2.0\n );\n\n this.panel.rotation.set(0, Math.PI, 0);\n this.add(this.panel);\n\n const grid = this.panel.addGrid();\n\n // 2. Status Text\n this.statusText = grid.addRow({ weight: 1 }).addText({\n text: this.exitPanelText,\n fontColor: '#ffffff',\n fontSize: .4,\n });\n\n // Orbiter\n const orbiter = grid.addOrbiter();\n orbiter.addExitButton();\n this.panel.updateLayouts();\n }\n```\n\nInitialize Class when loaded into the page:\n`// ⌄⌄⌄ Initialize ⌄⌄⌄`\n```js\n init() {\n console.log(\"Exit Button init!\",this.client);\n this.createExitPanel();\n }\n```","src/content/docs/05_Exit_Button.md","8a1b55e67864fa9e",{"html":119,"metadata":120},"\u003Cp>When in the WebXR environment using a headset, I could not figure out how to leave the experience, so I made an Exit Demo Panel.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">ExitButton.js\u003C/code> file.\u003C/p>\n\u003Cp>Create the constructor for the Class:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create constructor ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">constructor\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">super\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Keep a reference to the panel so we can destroy it later\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">exitPanelText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Exit Demo\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" constructor() { super(); // Keep a reference to the panel so we can destroy it later this.panel = null; this.statusText = null; this.exitPanelText = "Exit Demo"; }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Function to create a panel for the Exit Button:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create Exit Button panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createExitPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// SAFETY: If a panel already exists, don't create another one.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Creating Exit Button...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Create the Panel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">SpatialPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">width: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">height: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#2b2b2baa\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2.0\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">rotation\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">Math\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">PI\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addGrid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Status Text\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">exitPanelText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ffffff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">.4\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Orbiter\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">orbiter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addOrbiter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">orbiter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addExitButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateLayouts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" createExitPanel() { // SAFETY: If a panel already exists, don't create another one. if (this.panel) return; console.log("Creating Exit Button..."); // 1. Create the Panel this.panel = new xb.SpatialPanel({ width: 0.5, height: 0.5, backgroundColor: '#2b2b2baa' }); this.panel.position.set( 0, xb.user.height, 2.0 ); this.panel.rotation.set(0, Math.PI, 0); this.add(this.panel); const grid = this.panel.addGrid(); // 2. Status Text this.statusText = grid.addRow({ weight: 1 }).addText({ text: this.exitPanelText, fontColor: '#ffffff', fontSize: .4, }); // Orbiter const orbiter = grid.addOrbiter(); orbiter.addExitButton(); this.panel.updateLayouts(); }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Initialize Class when loaded into the page:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Initialize ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">init\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Exit Button init!\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createExitPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" init() { console.log("Exit Button init!",this.client); this.createExitPanel(); }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":121,"localImagePaths":122,"remoteImagePaths":123,"frontmatter":124,"imagePaths":125},[],[],[],{"title":110,"description":111},[],"06_add_to_xr_blocks",{"id":126,"data":128,"body":134,"filePath":135,"digest":136,"rendered":137},{"title":129,"description":130,"editUrl":16,"head":131,"template":32,"sidebar":132,"pagefind":16,"draft":22},"Add panels to XR Blocks","adding panels to WebXR application",[],{"hidden":22,"attrs":133},{},"Let's add the 2 panels to the application.\n\nThe following code will be placed in the `main.js` file.\n\nFirst, import the Panels:\n`// ⌄⌄⌄ import Vonage Call Panel and Exit Button ⌄⌄⌄`\n```js\nimport { VonageAudioCall } from './VonageAudioCall.js';\nimport { ExitPanel } from './ExitButton.js';\n```\n\nCreate instances and add to the application:\n`// ⌄⌄⌄ add Vonage Call Panel and Exit Button ⌄⌄⌄`\n```js\nxb.add(new VonageAudioCall());\nxb.add(new ExitPanel());\n```\n\n## Time to test the application\nRefresh the application and try to call the phone number that was purchased and assigned while running the setup script.\n\n> Note: You can find the phone number connected to your Vonage application in the `.env` file.","src/content/docs/06_Add_To_XR_Blocks.md","d3b20f81f928d1fb",{"html":138,"metadata":139},"\u003Cp>Let’s add the 2 panels to the application.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">main.js\u003C/code> file.\u003C/p>\n\u003Cp>First, import the Panels:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ import Vonage Call Panel and Exit Button ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { VonageAudioCall } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./VonageAudioCall.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { ExitPanel } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./ExitButton.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { VonageAudioCall } from './VonageAudioCall.js';import { ExitPanel } from './ExitButton.js';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Create instances and add to the application:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ add Vonage Call Panel and Exit Button ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">VonageAudioCall\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">());\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">ExitPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">());\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"xb.add(new VonageAudioCall());xb.add(new ExitPanel());\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"time-to-test-the-application\">Time to test the application\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#time-to-test-the-application\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “Time to test the application”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Refresh the application and try to call the phone number that was purchased and assigned while running the setup script.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Note: You can find the phone number connected to your Vonage application in the \u003Ccode dir=\"auto\">.env\u003C/code> file.\u003C/p>\n\u003C/blockquote>",{"headings":140,"localImagePaths":144,"remoteImagePaths":145,"frontmatter":146,"imagePaths":147},[141],{"depth":81,"slug":142,"text":143},"time-to-test-the-application","Time to test the application",[],[],{"title":129,"description":130},[],"07_congrats",{"id":148,"data":150,"body":156,"filePath":157,"digest":158,"rendered":159},{"title":151,"description":152,"editUrl":16,"head":153,"template":32,"sidebar":154,"pagefind":16,"draft":22},"Congratulations!","What's next.",[],{"hidden":22,"attrs":155},{},"## You did it!\n\nYou now have a WebXR application using XR Blocks and the Vonage Voice API that can receive phone calls.\n\n## What's Next?\n- Can you create a WebXR application that makes phone calls? How about a voice chat in a WebXR environment?\n- Learn more about the Vonage Voice API in our \u003Ca href=\"https://developer.vonage.com/en/voice/voice-api/overview\" target=\"_blank\">developer documenation\u003C/a>\n- Connect with us on \u003Ca href=\"https://x.com/vonagedev\" target=\"_blank\">Twitter / X\u003C/a> and \u003Ca href=\"https://www.linkedin.com/company/vonage-dev\" target=\"_blank\">LinkedIn\u003C/a>\n- Join our \u003Ca href=\"https://vonage.dev/slack\" target=\"_blank\">Developer Community Slack channel\u003C/a> to connect with others building with Vonage","src/content/docs/07_Congrats.md","8c617d22f873e7d6",{"html":160,"metadata":161},"\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"you-did-it\">You did it!\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#you-did-it\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “You did it!”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>You now have a WebXR application using XR Blocks and the Vonage Voice API that can receive phone calls.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"whats-next\">What’s Next?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#whats-next\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “What’s Next?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Can you create a WebXR application that makes phone calls? How about a voice chat in a WebXR environment?\u003C/li>\n\u003Cli>Learn more about the Vonage Voice API in our \u003Ca href=\"https://developer.vonage.com/en/voice/voice-api/overview\" target=\"_blank\">developer documenation\u003C/a>\u003C/li>\n\u003Cli>Connect with us on \u003Ca href=\"https://x.com/vonagedev\" target=\"_blank\">Twitter / X\u003C/a> and \u003Ca href=\"https://www.linkedin.com/company/vonage-dev\" target=\"_blank\">LinkedIn\u003C/a>\u003C/li>\n\u003Cli>Join our \u003Ca href=\"https://vonage.dev/slack\" target=\"_blank\">Developer Community Slack channel\u003C/a> to connect with others building with Vonage\u003C/li>\n\u003C/ul>",{"headings":162,"localImagePaths":169,"remoteImagePaths":170,"frontmatter":171,"imagePaths":172},[163,166],{"depth":81,"slug":164,"text":165},"you-did-it","You did it!",{"depth":81,"slug":167,"text":168},"whats-next","What’s Next?",[],[],{"title":151,"description":152},[]] \ No newline at end of file +[["Map",1,2,9,10],"meta::meta",["Map",3,4,5,6,7,8],"astro-version","5.18.1","content-config-digest","a30a942a2ceda2e1","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"where\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true,\"allowedHosts\":[]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[],\"remotePatterns\":[],\"responsiveStyles\":false},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":false,\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[null,null,null],\"rehypePlugins\":[[null,{\"experimentalHeadingIdCompat\":false}],null,[null,{\"themes\":[{\"name\":\"Night Owl No Italics\",\"type\":\"dark\",\"colors\":{\"focusBorder\":\"#122d42\",\"foreground\":\"#d6deeb\",\"disabledForeground\":\"#cccccc80\",\"descriptionForeground\":\"#d6deebb3\",\"errorForeground\":\"#ef5350\",\"icon.foreground\":\"#c5c5c5\",\"contrastActiveBorder\":null,\"contrastBorder\":\"#122d42\",\"textBlockQuote.background\":\"#7f7f7f1a\",\"textBlockQuote.border\":\"#007acc80\",\"textCodeBlock.background\":\"#4f4f4f\",\"textLink.activeForeground\":\"#3794ff\",\"textLink.foreground\":\"#3794ff\",\"textPreformat.foreground\":\"#d7ba7d\",\"textSeparator.foreground\":\"#ffffff2e\",\"editor.background\":\"#23262f\",\"editor.foreground\":\"#d6deeb\",\"editorLineNumber.foreground\":\"#4b6479\",\"editorLineNumber.activeForeground\":\"#c5e4fd\",\"editorActiveLineNumber.foreground\":\"#c6c6c6\",\"editor.selectionBackground\":\"#1d3b53\",\"editor.inactiveSelectionBackground\":\"#7e57c25a\",\"editor.selectionHighlightBackground\":\"#5f7e9779\",\"editorError.foreground\":\"#ef5350\",\"editorWarning.foreground\":\"#b39554\",\"editorInfo.foreground\":\"#3794ff\",\"editorHint.foreground\":\"#eeeeeeb2\",\"problemsErrorIcon.foreground\":\"#ef5350\",\"problemsWarningIcon.foreground\":\"#b39554\",\"problemsInfoIcon.foreground\":\"#3794ff\",\"editor.findMatchBackground\":\"#5f7e9779\",\"editor.findMatchHighlightBackground\":\"#1085bb5d\",\"editor.findRangeHighlightBackground\":\"#3a3d4166\",\"editorLink.activeForeground\":\"#4e94ce\",\"editorLightBulb.foreground\":\"#ffcc00\",\"editorLightBulbAutoFix.foreground\":\"#75beff\",\"diffEditor.insertedTextBackground\":\"#99b76d23\",\"diffEditor.insertedTextBorder\":\"#c5e47833\",\"diffEditor.removedTextBackground\":\"#ef535033\",\"diffEditor.removedTextBorder\":\"#ef53504d\",\"diffEditor.insertedLineBackground\":\"#9bb95533\",\"diffEditor.removedLineBackground\":\"#ff000033\",\"editorStickyScroll.background\":\"#011627\",\"editorStickyScrollHover.background\":\"#2a2d2e\",\"editorInlayHint.background\":\"#5f7e97cc\",\"editorInlayHint.foreground\":\"#ffffff\",\"editorInlayHint.typeBackground\":\"#5f7e97cc\",\"editorInlayHint.typeForeground\":\"#ffffff\",\"editorInlayHint.parameterBackground\":\"#5f7e97cc\",\"editorInlayHint.parameterForeground\":\"#ffffff\",\"editorPane.background\":\"#011627\",\"editorGroup.emptyBackground\":\"#011627\",\"editorGroup.focusedEmptyBorder\":null,\"editorGroupHeader.tabsBackground\":\"var(--sl-color-black)\",\"editorGroupHeader.tabsBorder\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"editorGroupHeader.noTabsBackground\":\"#011627\",\"editorGroupHeader.border\":null,\"editorGroup.border\":\"#011627\",\"editorGroup.dropBackground\":\"#7e57c273\",\"editorGroup.dropIntoPromptForeground\":\"#d6deeb\",\"editorGroup.dropIntoPromptBackground\":\"#021320\",\"editorGroup.dropIntoPromptBorder\":null,\"sideBySideEditor.horizontalBorder\":\"#011627\",\"sideBySideEditor.verticalBorder\":\"#011627\",\"scrollbar.shadow\":\"#010b14\",\"scrollbarSlider.background\":\"#ffffff17\",\"scrollbarSlider.hoverBackground\":\"#ffffff40\",\"scrollbarSlider.activeBackground\":\"#084d8180\",\"panel.background\":\"#011627\",\"panel.border\":\"#5f7e97\",\"panelTitle.activeBorder\":\"#5f7e97\",\"panelTitle.activeForeground\":\"#ffffffcc\",\"panelTitle.inactiveForeground\":\"#d6deeb80\",\"panelSectionHeader.background\":\"#80808051\",\"terminal.background\":\"#011627\",\"widget.shadow\":\"#011627\",\"editorWidget.background\":\"#021320\",\"editorWidget.foreground\":\"#d6deeb\",\"editorWidget.border\":\"#5f7e97\",\"quickInput.background\":\"#021320\",\"quickInput.foreground\":\"#d6deeb\",\"quickInputTitle.background\":\"#ffffff1a\",\"pickerGroup.foreground\":\"#d1aaff\",\"pickerGroup.border\":\"#011627\",\"editor.hoverHighlightBackground\":\"#7e57c25a\",\"editorHoverWidget.background\":\"#011627\",\"editorHoverWidget.foreground\":\"#d6deeb\",\"editorHoverWidget.border\":\"#5f7e97\",\"editorHoverWidget.statusBarBackground\":\"#011a2f\",\"titleBar.activeBackground\":\"var(--sl-color-black)\",\"titleBar.activeForeground\":\"var(--sl-color-text)\",\"titleBar.inactiveBackground\":\"#010e1a\",\"titleBar.inactiveForeground\":\"#eeefff99\",\"titleBar.border\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"toolbar.hoverBackground\":\"#5a5d5e50\",\"toolbar.activeBackground\":\"#63666750\",\"tab.activeBackground\":\"#0b2942\",\"tab.unfocusedActiveBackground\":\"#0b2942\",\"tab.inactiveBackground\":\"#01111d\",\"tab.unfocusedInactiveBackground\":\"#01111d\",\"tab.activeForeground\":\"var(--sl-color-text)\",\"tab.inactiveForeground\":\"#5f7e97\",\"tab.unfocusedActiveForeground\":\"#5f7e97\",\"tab.unfocusedInactiveForeground\":\"#5f7e97\",\"tab.hoverBackground\":null,\"tab.unfocusedHoverBackground\":null,\"tab.hoverForeground\":null,\"tab.unfocusedHoverForeground\":null,\"tab.border\":\"#272b3b\",\"tab.lastPinnedBorder\":\"#585858\",\"tab.activeBorder\":\"transparent\",\"tab.unfocusedActiveBorder\":\"#262a39\",\"tab.activeBorderTop\":\"var(--sl-color-accent-high)\",\"tab.unfocusedActiveBorderTop\":null,\"tab.hoverBorder\":null,\"tab.unfocusedHoverBorder\":null,\"tab.activeModifiedBorder\":\"#3399cc\",\"tab.inactiveModifiedBorder\":\"#3399cc80\",\"tab.unfocusedActiveModifiedBorder\":\"#3399cc80\",\"tab.unfocusedInactiveModifiedBorder\":\"#3399cc40\",\"badge.background\":\"#5f7e97\",\"badge.foreground\":\"#ffffff\",\"button.background\":\"#7e57c2cc\",\"button.foreground\":\"#ffffffcc\",\"button.border\":\"#122d42\",\"button.separator\":\"#ffffff52\",\"button.hoverBackground\":\"#7e57c2\",\"button.secondaryBackground\":\"#3a3d41\",\"button.secondaryForeground\":\"#ffffff\",\"button.secondaryHoverBackground\":\"#46494e\",\"dropdown.background\":\"#011627\",\"dropdown.foreground\":\"#ffffffcc\",\"dropdown.border\":\"#5f7e97\",\"list.activeSelectionBackground\":\"#234d708c\",\"list.activeSelectionForeground\":\"#ffffff\",\"tree.indentGuidesStroke\":\"#585858\",\"input.background\":\"#0b253a\",\"input.foreground\":\"#ffffffcc\",\"input.placeholderForeground\":\"#5f7e97\",\"inputOption.activeBorder\":\"#ffffffcc\",\"inputOption.hoverBackground\":\"#5a5d5e80\",\"inputOption.activeBackground\":\"#122d4266\",\"inputOption.activeForeground\":\"#ffffff\",\"inputValidation.infoBackground\":\"#00589ef2\",\"inputValidation.infoBorder\":\"#64b5f6\",\"inputValidation.warningBackground\":\"#675700f2\",\"inputValidation.warningBorder\":\"#ffca28\",\"inputValidation.errorBackground\":\"#ab0300f2\",\"inputValidation.errorBorder\":\"#ef5350\",\"keybindingLabel.background\":\"#8080802b\",\"keybindingLabel.foreground\":\"#cccccc\",\"keybindingLabel.border\":\"#33333399\",\"keybindingLabel.bottomBorder\":\"#44444499\",\"menu.foreground\":\"#ffffffcc\",\"menu.background\":\"#011627\",\"menu.selectionForeground\":\"#ffffff\",\"menu.selectionBackground\":\"#234d708c\",\"menu.separatorBackground\":\"#606060\",\"editor.snippetTabstopHighlightBackground\":\"#7c7c74c\",\"editor.snippetFinalTabstopHighlightBorder\":\"#525252\",\"terminal.ansiBlack\":\"#011627\",\"terminal.ansiRed\":\"#ef5350\",\"terminal.ansiGreen\":\"#22da6e\",\"terminal.ansiYellow\":\"#c5e478\",\"terminal.ansiBlue\":\"#82aaff\",\"terminal.ansiMagenta\":\"#c792ea\",\"terminal.ansiCyan\":\"#21c7a8\",\"terminal.ansiWhite\":\"#ffffff\",\"terminal.ansiBrightBlack\":\"#575656\",\"terminal.ansiBrightRed\":\"#ef5350\",\"terminal.ansiBrightGreen\":\"#22da6e\",\"terminal.ansiBrightYellow\":\"#ffeb95\",\"terminal.ansiBrightBlue\":\"#82aaff\",\"terminal.ansiBrightMagenta\":\"#c792ea\",\"terminal.ansiBrightCyan\":\"#7fdbca\",\"terminal.ansiBrightWhite\":\"#ffffff\",\"selection.background\":\"#4373c2\",\"input.border\":\"#5f7e97\",\"punctuation.definition.generic.begin.html\":\"#ef5350f2\",\"progress.background\":\"#7e57c2\",\"breadcrumb.foreground\":\"#a599e9\",\"breadcrumb.focusForeground\":\"#ffffff\",\"breadcrumb.activeSelectionForeground\":\"#ffffff\",\"breadcrumbPicker.background\":\"#001122\",\"list.invalidItemForeground\":\"#975f94\",\"list.dropBackground\":\"#011627\",\"list.focusBackground\":\"#010d18\",\"list.focusForeground\":\"#ffffff\",\"list.highlightForeground\":\"#ffffff\",\"list.hoverBackground\":\"#011627\",\"list.hoverForeground\":\"#ffffff\",\"list.inactiveSelectionBackground\":\"#0e293f\",\"list.inactiveSelectionForeground\":\"#5f7e97\",\"activityBar.background\":\"#011627\",\"activityBar.dropBackground\":\"#5f7e97\",\"activityBar.foreground\":\"#5f7e97\",\"activityBar.border\":\"#011627\",\"activityBarBadge.background\":\"#44596b\",\"activityBarBadge.foreground\":\"#ffffff\",\"sideBar.background\":\"#011627\",\"sideBar.foreground\":\"#89a4bb\",\"sideBar.border\":\"#011627\",\"sideBarTitle.foreground\":\"#5f7e97\",\"sideBarSectionHeader.background\":\"#011627\",\"sideBarSectionHeader.foreground\":\"#5f7e97\",\"editorCursor.foreground\":\"#80a4c2\",\"editor.wordHighlightBackground\":\"#f6bbe533\",\"editor.wordHighlightStrongBackground\":\"#e2a2f433\",\"editor.lineHighlightBackground\":\"#0003\",\"editor.rangeHighlightBackground\":\"#7e57c25a\",\"editorIndentGuide.background\":\"#5e81ce52\",\"editorIndentGuide.activeBackground\":\"#7e97ac\",\"editorRuler.foreground\":\"#5e81ce52\",\"editorCodeLens.foreground\":\"#5e82ceb4\",\"editorBracketMatch.background\":\"#5f7e974d\",\"editorOverviewRuler.currentContentForeground\":\"#7e57c2\",\"editorOverviewRuler.incomingContentForeground\":\"#7e57c2\",\"editorOverviewRuler.commonContentForeground\":\"#7e57c2\",\"editorGutter.background\":\"#011627\",\"editorGutter.modifiedBackground\":\"#e2b93d\",\"editorGutter.addedBackground\":\"#9ccc65\",\"editorGutter.deletedBackground\":\"#ef5350\",\"editorSuggestWidget.background\":\"#2c3043\",\"editorSuggestWidget.border\":\"#2b2f40\",\"editorSuggestWidget.foreground\":\"#d6deeb\",\"editorSuggestWidget.highlightForeground\":\"#ffffff\",\"editorSuggestWidget.selectedBackground\":\"#5f7e97\",\"debugExceptionWidget.background\":\"#011627\",\"debugExceptionWidget.border\":\"#5f7e97\",\"editorMarkerNavigation.background\":\"#0b2942\",\"editorMarkerNavigationError.background\":\"#ef5350\",\"editorMarkerNavigationWarning.background\":\"#ffca28\",\"peekView.border\":\"#5f7e97\",\"peekViewEditor.background\":\"#011627\",\"peekViewEditor.matchHighlightBackground\":\"#7e57c25a\",\"peekViewResult.background\":\"#011627\",\"peekViewResult.fileForeground\":\"#5f7e97\",\"peekViewResult.lineForeground\":\"#5f7e97\",\"peekViewResult.matchHighlightBackground\":\"#ffffffcc\",\"peekViewResult.selectionBackground\":\"#2e3250\",\"peekViewResult.selectionForeground\":\"#5f7e97\",\"peekViewTitle.background\":\"#011627\",\"peekViewTitleDescription.foreground\":\"#697098\",\"peekViewTitleLabel.foreground\":\"#5f7e97\",\"merge.currentHeaderBackground\":\"#5f7e97\",\"merge.incomingHeaderBackground\":\"#7e57c25a\",\"statusBar.background\":\"#011627\",\"statusBar.foreground\":\"#5f7e97\",\"statusBar.border\":\"#262a39\",\"statusBar.debuggingBackground\":\"#202431\",\"statusBar.debuggingBorder\":\"#1f2330\",\"statusBar.noFolderBackground\":\"#011627\",\"statusBar.noFolderBorder\":\"#25293a\",\"statusBarItem.activeBackground\":\"#202431\",\"statusBarItem.hoverBackground\":\"#202431\",\"statusBarItem.prominentBackground\":\"#202431\",\"statusBarItem.prominentHoverBackground\":\"#202431\",\"notifications.background\":\"#01111d\",\"notifications.border\":\"#262a39\",\"notificationCenter.border\":\"#262a39\",\"notificationToast.border\":\"#262a39\",\"notifications.foreground\":\"#ffffffcc\",\"notificationLink.foreground\":\"#80cbc4\",\"extensionButton.prominentForeground\":\"#ffffffcc\",\"extensionButton.prominentBackground\":\"#7e57c2cc\",\"extensionButton.prominentHoverBackground\":\"#7e57c2\",\"terminal.selectionBackground\":\"#1b90dd4d\",\"terminalCursor.background\":\"#234d70\",\"debugToolBar.background\":\"#011627\",\"welcomePage.buttonBackground\":\"#011627\",\"welcomePage.buttonHoverBackground\":\"#011627\",\"walkThrough.embeddedEditorBackground\":\"#011627\",\"gitDecoration.modifiedResourceForeground\":\"#a2bffc\",\"gitDecoration.deletedResourceForeground\":\"#ef535090\",\"gitDecoration.untrackedResourceForeground\":\"#c5e478ff\",\"gitDecoration.ignoredResourceForeground\":\"#395a75\",\"gitDecoration.conflictingResourceForeground\":\"#ffeb95cc\",\"source.elm\":\"#5f7e97\",\"string.quoted.single.js\":\"#ffffff\",\"meta.objectliteral.js\":\"#82aaff\"},\"fg\":\"#d6deeb\",\"bg\":\"#23262f\",\"semanticHighlighting\":false,\"settings\":[{\"name\":\"Changed\",\"scope\":[\"markup.changed\",\"meta.diff.header.git\",\"meta.diff.header.from-file\",\"meta.diff.header.to-file\"],\"settings\":{\"foreground\":\"#a2bffc\"}},{\"name\":\"Deleted\",\"scope\":[\"markup.deleted.diff\"],\"settings\":{\"foreground\":\"#f27775fe\"}},{\"name\":\"Inserted\",\"scope\":[\"markup.inserted.diff\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Global settings\",\"settings\":{\"background\":\"#011627\",\"foreground\":\"#d6deeb\"}},{\"name\":\"Comment\",\"scope\":[\"comment\"],\"settings\":{\"foreground\":\"#919f9f\",\"fontStyle\":\"\"}},{\"name\":\"String\",\"scope\":[\"string\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"String Quoted\",\"scope\":[\"string.quoted\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"Support Constant Math\",\"scope\":[\"support.constant.math\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Number\",\"scope\":[\"constant.numeric\",\"constant.character.numeric\"],\"settings\":{\"foreground\":\"#f78c6c\",\"fontStyle\":\"\"}},{\"name\":\"Built-in constant\",\"scope\":[\"constant.language\",\"punctuation.definition.constant\",\"variable.other.constant\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"User-defined constant\",\"scope\":[\"constant.character\",\"constant.other\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Constant Character Escape\",\"scope\":[\"constant.character.escape\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"RegExp String\",\"scope\":[\"string.regexp\",\"string.regexp keyword.other\"],\"settings\":{\"foreground\":\"#5ca7e4\"}},{\"name\":\"Comma in functions\",\"scope\":[\"meta.function punctuation.separator.comma\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"Variable\",\"scope\":[\"variable\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Keyword\",\"scope\":[\"punctuation.accessor\",\"keyword\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Storage\",\"scope\":[\"storage\",\"meta.var.expr\",\"meta.class meta.method.declaration meta.var.expr storage.type.js\",\"storage.type.property.js\",\"storage.type.property.ts\",\"storage.type.property.tsx\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type.function.arrow.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Class name\",\"scope\":[\"entity.name.class\",\"meta.class entity.name.type.class\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Inherited class\",\"scope\":[\"entity.other.inherited-class\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Function name\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Meta Tag\",\"scope\":[\"punctuation.definition.tag\",\"meta.tag\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"HTML Tag names\",\"scope\":[\"entity.name.tag\",\"meta.tag.other.html\",\"meta.tag.other.js\",\"meta.tag.other.tsx\",\"entity.name.tag.tsx\",\"entity.name.tag.js\",\"entity.name.tag\",\"meta.tag.js\",\"meta.tag.tsx\",\"meta.tag.html\"],\"settings\":{\"foreground\":\"#caece6\",\"fontStyle\":\"\"}},{\"name\":\"Tag attribute\",\"scope\":[\"entity.other.attribute-name\"],\"settings\":{\"fontStyle\":\"\",\"foreground\":\"#c5e478\"}},{\"name\":\"Entity Name Tag Custom\",\"scope\":[\"entity.name.tag.custom\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Library (function & constant)\",\"scope\":[\"support.function\",\"support.constant\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Support Constant Property Value meta\",\"scope\":[\"support.constant.meta.property-value\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Library class/type\",\"scope\":[\"support.type\",\"support.class\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Support Variable DOM\",\"scope\":[\"support.variable.dom\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Invalid\",\"scope\":[\"invalid\"],\"settings\":{\"background\":\"#ff2c83\",\"foreground\":\"#ffffff\"}},{\"name\":\"Invalid deprecated\",\"scope\":[\"invalid.deprecated\"],\"settings\":{\"foreground\":\"#ffffff\",\"background\":\"#d3423e\"}},{\"name\":\"Keyword Operator\",\"scope\":[\"keyword.operator\"],\"settings\":{\"foreground\":\"#7fdbca\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Relational\",\"scope\":[\"keyword.operator.relational\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Assignment\",\"scope\":[\"keyword.operator.assignment\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Arithmetic\",\"scope\":[\"keyword.operator.arithmetic\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Bitwise\",\"scope\":[\"keyword.operator.bitwise\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Increment\",\"scope\":[\"keyword.operator.increment\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Ternary\",\"scope\":[\"keyword.operator.ternary\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Double-Slashed Comment\",\"scope\":[\"comment.line.double-slash\"],\"settings\":{\"foreground\":\"#919f9f\"}},{\"name\":\"Object\",\"scope\":[\"object\"],\"settings\":{\"foreground\":\"#cdebf7\"}},{\"name\":\"Null\",\"scope\":[\"constant.language.null\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Meta Brace\",\"scope\":[\"meta.brace\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Meta Delimiter Period\",\"scope\":[\"meta.delimiter.period\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Punctuation Definition String\",\"scope\":[\"punctuation.definition.string\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Punctuation Definition String Markdown\",\"scope\":[\"punctuation.definition.string.begin.markdown\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Boolean\",\"scope\":[\"constant.language.boolean\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Object Comma\",\"scope\":[\"object.comma\"],\"settings\":{\"foreground\":\"#ffffff\"}},{\"name\":\"Variable Parameter Function\",\"scope\":[\"variable.parameter.function\"],\"settings\":{\"foreground\":\"#7fdbca\",\"fontStyle\":\"\"}},{\"name\":\"Support Type Property Name & entity name tags\",\"scope\":[\"support.type.vendor.property-name\",\"support.constant.vendor.property-value\",\"support.type.property-name\",\"meta.property-list entity.name.tag\"],\"settings\":{\"foreground\":\"#80cbc4\",\"fontStyle\":\"\"}},{\"name\":\"Entity Name tag reference in stylesheets\",\"scope\":[\"meta.property-list entity.name.tag.reference\"],\"settings\":{\"foreground\":\"#57eaf1\"}},{\"name\":\"Constant Other Color RGB Value Punctuation Definition Constant\",\"scope\":[\"constant.other.color.rgb-value punctuation.definition.constant\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Constant Other Color\",\"scope\":[\"constant.other.color\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Keyword Other Unit\",\"scope\":[\"keyword.other.unit\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Meta Selector\",\"scope\":[\"meta.selector\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Entity Other Attribute Name Id\",\"scope\":[\"entity.other.attribute-name.id\"],\"settings\":{\"foreground\":\"#fad430\"}},{\"name\":\"Meta Property Name\",\"scope\":[\"meta.property-name\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Doctypes\",\"scope\":[\"entity.name.tag.doctype\",\"meta.tag.sgml.doctype\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Punctuation Definition Parameters\",\"scope\":[\"punctuation.definition.parameters\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Keyword Control Operator\",\"scope\":[\"keyword.control.operator\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Keyword Operator Logical\",\"scope\":[\"keyword.operator.logical\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Variable Instances\",\"scope\":[\"variable.instance\",\"variable.other.instance\",\"variable.readwrite.instance\",\"variable.other.readwrite.instance\",\"variable.other.property\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Variable Property Other object property\",\"scope\":[\"variable.other.object.property\"],\"settings\":{\"foreground\":\"#faf39f\",\"fontStyle\":\"\"}},{\"name\":\"Variable Property Other object\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Entity Name Function\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#82aaff\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Comparison, returns, imports, and Keyword Operator Ruby\",\"scope\":[\"keyword.control.conditional.js\",\"keyword.operator.comparison\",\"keyword.control.flow.js\",\"keyword.control.flow.ts\",\"keyword.control.flow.tsx\",\"keyword.control.ruby\",\"keyword.control.def.ruby\",\"keyword.control.loop.js\",\"keyword.control.loop.ts\",\"keyword.control.import.js\",\"keyword.control.import.ts\",\"keyword.control.import.tsx\",\"keyword.control.from.js\",\"keyword.control.from.ts\",\"keyword.control.from.tsx\",\"keyword.control.conditional.js\",\"keyword.control.conditional.ts\",\"keyword.control.switch.js\",\"keyword.control.switch.ts\",\"keyword.operator.instanceof.js\",\"keyword.operator.expression.instanceof.ts\",\"keyword.operator.expression.instanceof.tsx\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords\",\"scope\":[\"support.constant\",\"keyword.other.special-method\",\"keyword.other.new\",\"keyword.other.debugger\",\"keyword.control\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Support Function\",\"scope\":[\"support.function\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Invalid Broken\",\"scope\":[\"invalid.broken\"],\"settings\":{\"foreground\":\"#989da0\",\"background\":\"#F78C6C\"}},{\"name\":\"Invalid Unimplemented\",\"scope\":[\"invalid.unimplemented\"],\"settings\":{\"background\":\"#8BD649\",\"foreground\":\"#ffffff\"}},{\"name\":\"Invalid Illegal\",\"scope\":[\"invalid.illegal\"],\"settings\":{\"foreground\":\"#ffffff\",\"background\":\"#ec5f67\"}},{\"name\":\"Language Variable\",\"scope\":[\"variable.language\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Support Variable Property\",\"scope\":[\"support.variable.property\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Variable Function\",\"scope\":[\"variable.function\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Variable Interpolation\",\"scope\":[\"variable.interpolation\"],\"settings\":{\"foreground\":\"#ef787f\"}},{\"name\":\"Meta Function Call\",\"scope\":[\"meta.function-call\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Punctuation Section Embedded\",\"scope\":[\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#e2817f\"}},{\"name\":\"Punctuation Tweaks\",\"scope\":[\"punctuation.terminator.expression\",\"punctuation.definition.arguments\",\"punctuation.definition.array\",\"punctuation.section.array\",\"meta.array\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"More Punctuation Tweaks\",\"scope\":[\"punctuation.definition.list.begin\",\"punctuation.definition.list.end\",\"punctuation.separator.arguments\",\"punctuation.definition.list\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Template Strings\",\"scope\":[\"string.template meta.template.expression\"],\"settings\":{\"foreground\":\"#e2817f\"}},{\"name\":\"Backticks(``) in Template Strings\",\"scope\":[\"string.template punctuation.definition.string\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Italics\",\"scope\":[\"italic\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"italic\"}},{\"name\":\"Bold\",\"scope\":[\"bold\"],\"settings\":{\"foreground\":\"#c5e478\",\"fontStyle\":\"bold\"}},{\"name\":\"Quote\",\"scope\":[\"quote\"],\"settings\":{\"foreground\":\"#969bb7\",\"fontStyle\":\"\"}},{\"name\":\"Raw Code\",\"scope\":[\"raw\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"CoffeeScript Variable Assignment\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#31e1eb\"}},{\"name\":\"CoffeeScript Parameter Function\",\"scope\":[\"variable.parameter.function.coffee\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"CoffeeScript Assignments\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"C# Readwrite Variables\",\"scope\":[\"variable.other.readwrite.cs\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C# Classes & Storage types\",\"scope\":[\"entity.name.type.class.cs\",\"storage.type.cs\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"C# Namespaces\",\"scope\":[\"entity.name.type.namespace.cs\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"C# Unquoted String Zone\",\"scope\":[\"string.unquoted.preprocessor.message.cs\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C# Region\",\"scope\":[\"punctuation.separator.hash.cs\",\"keyword.preprocessor.region.cs\",\"keyword.preprocessor.endregion.cs\"],\"settings\":{\"foreground\":\"#ffcb8b\",\"fontStyle\":\"bold\"}},{\"name\":\"C# Other Variables\",\"scope\":[\"variable.other.object.cs\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"C# Enum\",\"scope\":[\"entity.name.type.enum.cs\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Dart String\",\"scope\":[\"string.interpolated.single.dart\",\"string.interpolated.double.dart\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Dart Class\",\"scope\":[\"support.class.dart\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Tag names in Stylesheets\",\"scope\":[\"entity.name.tag.css\",\"entity.name.tag.less\",\"entity.name.tag.custom.css\",\"support.constant.property-value.css\"],\"settings\":{\"foreground\":\"#ff6d6d\",\"fontStyle\":\"\"}},{\"name\":\"Wildcard(*) selector in Stylesheets\",\"scope\":[\"entity.name.tag.wildcard.css\",\"entity.name.tag.wildcard.less\",\"entity.name.tag.wildcard.scss\",\"entity.name.tag.wildcard.sass\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"CSS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Attribute Name for CSS\",\"scope\":[\"meta.attribute-selector.css entity.other.attribute-name.attribute\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Elixir Classes\",\"scope\":[\"source.elixir support.type.elixir\",\"source.elixir meta.module.elixir entity.name.class.elixir\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Elixir Functions\",\"scope\":[\"source.elixir entity.name.function\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir Constants\",\"scope\":[\"source.elixir constant.other.symbol.elixir\",\"source.elixir constant.other.keywords.elixir\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Elixir String Punctuations\",\"scope\":[\"source.elixir punctuation.definition.string\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir\",\"scope\":[\"source.elixir variable.other.readwrite.module.elixir\",\"source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir Binary Punctuations\",\"scope\":[\"source.elixir .punctuation.binary.elixir\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Closure Constant Keyword\",\"scope\":[\"constant.keyword.clojure\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Go Function Calls\",\"scope\":[\"source.go meta.function-call.go\"],\"settings\":{\"foreground\":\"#dddddd\"}},{\"name\":\"Go Keywords\",\"scope\":[\"source.go keyword.package.go\",\"source.go keyword.import.go\",\"source.go keyword.function.go\",\"source.go keyword.type.go\",\"source.go keyword.struct.go\",\"source.go keyword.interface.go\",\"source.go keyword.const.go\",\"source.go keyword.var.go\",\"source.go keyword.map.go\",\"source.go keyword.channel.go\",\"source.go keyword.control.go\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Go Constants e.g. nil, string format (%s, %d, etc.)\",\"scope\":[\"source.go constant.language.go\",\"source.go constant.other.placeholder.go\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"C++ Functions\",\"scope\":[\"entity.name.function.preprocessor.cpp\",\"entity.scope.name.cpp\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"C++ Meta Namespace\",\"scope\":[\"meta.namespace-block.cpp\"],\"settings\":{\"foreground\":\"#e0dec6\"}},{\"name\":\"C++ Language Primitive Storage\",\"scope\":[\"storage.type.language.primitive.cpp\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"C++ Preprocessor Macro\",\"scope\":[\"meta.preprocessor.macro.cpp\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C++ Variable Parameter\",\"scope\":[\"variable.parameter\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Powershell Variables\",\"scope\":[\"variable.other.readwrite.powershell\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Powershell Function\",\"scope\":[\"support.function.powershell\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"ID Attribute Name in HTML\",\"scope\":[\"entity.other.attribute-name.id.html\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"HTML Punctuation Definition Tag\",\"scope\":[\"punctuation.definition.tag.html\"],\"settings\":{\"foreground\":\"#6ae9f0\"}},{\"name\":\"HTML Doctype\",\"scope\":[\"meta.tag.sgml.doctype.html\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Classes\",\"scope\":[\"meta.class entity.name.type.class.js\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"JavaScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.js\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"JavaScript Terminator\",\"scope\":[\"terminator.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Meta Punctuation Definition\",\"scope\":[\"meta.js punctuation.definition.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Entity Names in Code Documentations\",\"scope\":[\"entity.name.type.instance.jsdoc\",\"entity.name.type.instance.phpdoc\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"Other Variables in Code Documentations\",\"scope\":[\"variable.other.jsdoc\",\"variable.other.phpdoc\"],\"settings\":{\"foreground\":\"#78ccf0\"}},{\"name\":\"JavaScript module imports and exports\",\"scope\":[\"variable.other.meta.import.js\",\"meta.import.js variable.other\",\"variable.other.meta.export.js\",\"meta.export.js variable.other\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Variable Parameter Function\",\"scope\":[\"variable.parameter.function.js\"],\"settings\":{\"foreground\":\"#8b96ea\"}},{\"name\":\"JavaScript[React] Variable Other Object\",\"scope\":[\"variable.other.object.js\",\"variable.other.object.jsx\",\"variable.object.property.js\",\"variable.object.property.jsx\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Variables\",\"scope\":[\"variable.js\",\"variable.other.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Entity Name Type\",\"scope\":[\"entity.name.type.js\",\"entity.name.type.module.js\"],\"settings\":{\"foreground\":\"#ffcb8b\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Support Classes\",\"scope\":[\"support.class.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JSON Property Names\",\"scope\":[\"support.type.property-name.json\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"JSON Support Constants\",\"scope\":[\"support.constant.json\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"JSON Property values (string)\",\"scope\":[\"meta.structure.dictionary.value.json string.quoted.double\"],\"settings\":{\"foreground\":\"#c789d6\"}},{\"name\":\"Strings in JSON values\",\"scope\":[\"string.quoted.double.json punctuation.definition.string.json\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Specific JSON Property values like null\",\"scope\":[\"meta.structure.dictionary.json meta.structure.dictionary.value constant.language\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"JavaScript Other Variable\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Ruby Variables\",\"scope\":[\"variable.other.ruby\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Ruby Class\",\"scope\":[\"entity.name.type.class.ruby\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"Ruby Hashkeys\",\"scope\":[\"constant.language.symbol.hashkey.ruby\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"LESS Tag names\",\"scope\":[\"entity.name.tag.less\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"LESS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Attribute Name for LESS\",\"scope\":[\"meta.attribute-selector.less entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Markdown Headings\",\"scope\":[\"markup.heading.markdown\",\"markup.heading.setext.1.markdown\",\"markup.heading.setext.2.markdown\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown Italics\",\"scope\":[\"markup.italic.markdown\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"italic\"}},{\"name\":\"Markdown Bold\",\"scope\":[\"markup.bold.markdown\"],\"settings\":{\"foreground\":\"#c5e478\",\"fontStyle\":\"bold\"}},{\"name\":\"Markdown Quote + others\",\"scope\":[\"markup.quote.markdown\"],\"settings\":{\"foreground\":\"#969bb7\",\"fontStyle\":\"\"}},{\"name\":\"Markdown Raw Code + others\",\"scope\":[\"markup.inline.raw.markdown\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Markdown Links\",\"scope\":[\"markup.underline.link.markdown\",\"markup.underline.link.image.markdown\"],\"settings\":{\"foreground\":\"#ff869a\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Link Title and Description\",\"scope\":[\"string.other.link.title.markdown\",\"string.other.link.description.markdown\"],\"settings\":{\"foreground\":\"#d6deeb\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Punctuation\",\"scope\":[\"punctuation.definition.string.markdown\",\"punctuation.definition.string.begin.markdown\",\"punctuation.definition.string.end.markdown\",\"meta.link.inline.markdown punctuation.definition.string\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown MetaData Punctuation\",\"scope\":[\"punctuation.definition.metadata.markdown\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Markdown List Punctuation\",\"scope\":[\"beginning.punctuation.definition.list.markdown\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown Inline Raw String\",\"scope\":[\"markup.inline.raw.string.markdown\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"PHP Variables\",\"scope\":[\"variable.other.php\"],\"settings\":{\"foreground\":\"#bec5d4\"}},{\"name\":\"Support Classes in PHP\",\"scope\":[\"support.class.php\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Punctuations in PHP function calls\",\"scope\":[\"meta.function-call.php punctuation\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"PHP Global Variables\",\"scope\":[\"variable.other.global.php\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Declaration Punctuation in PHP Global Variables\",\"scope\":[\"variable.other.global.php punctuation.definition.variable\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Language Constants in Python\",\"scope\":[\"constant.language.python\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Python Function Parameter and Arguments\",\"scope\":[\"variable.parameter.function.python\",\"meta.function-call.arguments.python\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Python Function Call\",\"scope\":[\"meta.function-call.python\",\"meta.function-call.generic.python\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"Punctuations in Python\",\"scope\":[\"punctuation.python\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Decorator Functions in Python\",\"scope\":[\"entity.name.function.decorator.python\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Python Language Variable\",\"scope\":[\"source.python variable.language.special\"],\"settings\":{\"foreground\":\"#8eace3\"}},{\"name\":\"Python import control keyword\",\"scope\":[\"keyword.control\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"SCSS Variable\",\"scope\":[\"variable.scss\",\"variable.sass\",\"variable.parameter.url.scss\",\"variable.parameter.url.sass\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#bec5d4\"}},{\"name\":\"Attribute Name for SASS\",\"scope\":[\"meta.attribute-selector.scss entity.other.attribute-name.attribute\",\"meta.attribute-selector.sass entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Tag names in SASS\",\"scope\":[\"entity.name.tag.scss\",\"entity.name.tag.sass\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"SASS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.scss\",\"keyword.other.unit.sass\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"TypeScript[React] Variables and Object Properties\",\"scope\":[\"variable.other.readwrite.alias.ts\",\"variable.other.readwrite.alias.tsx\",\"variable.other.readwrite.ts\",\"variable.other.readwrite.tsx\",\"variable.other.object.ts\",\"variable.other.object.tsx\",\"variable.object.property.ts\",\"variable.object.property.tsx\",\"variable.other.ts\",\"variable.other.tsx\",\"variable.tsx\",\"variable.ts\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript[React] Entity Name Types\",\"scope\":[\"entity.name.type.ts\",\"entity.name.type.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript[React] Node Classes\",\"scope\":[\"support.class.node.ts\",\"support.class.node.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"TypeScript[React] Entity Name Types as Parameters\",\"scope\":[\"meta.type.parameters.ts entity.name.type\",\"meta.type.parameters.tsx entity.name.type\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"TypeScript[React] Import/Export Punctuations\",\"scope\":[\"meta.import.ts punctuation.definition.block\",\"meta.import.tsx punctuation.definition.block\",\"meta.export.ts punctuation.definition.block\",\"meta.export.tsx punctuation.definition.block\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.decorator punctuation.decorator.ts\",\"meta.decorator punctuation.decorator.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.tag.js meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"YAML Entity Name Tags\",\"scope\":[\"entity.name.tag.yaml\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"JavaScript Variable Other ReadWrite\",\"scope\":[\"variable.other.readwrite.js\",\"variable.parameter\"],\"settings\":{\"foreground\":\"#d7dbe0\"}},{\"name\":\"Support Class Component\",\"scope\":[\"support.class.component.js\",\"support.class.component.tsx\"],\"settings\":{\"foreground\":\"#f78c6c\",\"fontStyle\":\"\"}},{\"name\":\"Text nested in React tags\",\"scope\":[\"meta.jsx.children\",\"meta.jsx.children.js\",\"meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript Classes\",\"scope\":[\"meta.class entity.name.type.class.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript Entity Name Type\",\"scope\":[\"entity.name.type.tsx\",\"entity.name.type.module.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript Class Variable Keyword\",\"scope\":[\"meta.class.ts meta.var.expr.ts storage.type.ts\",\"meta.class.tsx meta.var.expr.tsx storage.type.tsx\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"TypeScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.ts\",\"meta.method.declaration storage.type.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"normalize font style of certain components\",\"scope\":[\"meta.property-list.css meta.property-value.css variable.other.less\",\"meta.property-list.scss variable.scss\",\"meta.property-list.sass variable.sass\",\"meta.brace\",\"keyword.operator.operator\",\"keyword.operator.or.regexp\",\"keyword.operator.expression.in\",\"keyword.operator.relational\",\"keyword.operator.assignment\",\"keyword.operator.comparison\",\"keyword.operator.type\",\"keyword.operator\",\"keyword\",\"punctuation.definition.string\",\"punctuation\",\"variable.other.readwrite.js\",\"storage.type\",\"source.css\",\"string.quoted\"],\"settings\":{\"fontStyle\":\"\"}}],\"styleOverrides\":{\"frames\":{\"editorBackground\":\"var(--sl-color-gray-6)\",\"terminalBackground\":\"var(--sl-color-gray-6)\",\"editorActiveTabBackground\":\"var(--sl-color-gray-6)\",\"terminalTitlebarDotsForeground\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"terminalTitlebarDotsOpacity\":\"0.75\",\"inlineButtonForeground\":\"var(--sl-color-text)\",\"frameBoxShadowCssValue\":\"none\"},\"textMarkers\":{\"markBackground\":\"#ffffff17\",\"markBorderColor\":\"#ffffff40\"}}},{\"name\":\"Night Owl Light\",\"type\":\"light\",\"colors\":{\"focusBorder\":\"#93a1a1\",\"foreground\":\"#403f53\",\"disabledForeground\":\"#61616180\",\"descriptionForeground\":\"#403f53\",\"errorForeground\":\"#403f53\",\"icon.foreground\":\"#424242\",\"contrastActiveBorder\":null,\"contrastBorder\":null,\"textBlockQuote.background\":\"#7f7f7f1a\",\"textBlockQuote.border\":\"#007acc80\",\"textCodeBlock.background\":\"#dcdcdc66\",\"textLink.activeForeground\":\"#006ab1\",\"textLink.foreground\":\"#006ab1\",\"textPreformat.foreground\":\"#a31515\",\"textSeparator.foreground\":\"#0000002e\",\"editor.background\":\"#f6f7f9\",\"editor.foreground\":\"#403f53\",\"editorLineNumber.foreground\":\"#90a7b2\",\"editorLineNumber.activeForeground\":\"#403f53\",\"editorActiveLineNumber.foreground\":\"#0b216f\",\"editor.selectionBackground\":\"#e0e0e0\",\"editor.inactiveSelectionBackground\":\"#e0e0e080\",\"editor.selectionHighlightBackground\":\"#339cec33\",\"editorError.foreground\":\"#e64d49\",\"editorWarning.foreground\":\"#daaa01\",\"editorInfo.foreground\":\"#1a85ff\",\"editorHint.foreground\":\"#6c6c6c\",\"problemsErrorIcon.foreground\":\"#e64d49\",\"problemsWarningIcon.foreground\":\"#daaa01\",\"problemsInfoIcon.foreground\":\"#1a85ff\",\"editor.findMatchBackground\":\"#93a1a16c\",\"editor.findMatchHighlightBackground\":\"#93a1a16c\",\"editor.findRangeHighlightBackground\":\"#7497a633\",\"editorLink.activeForeground\":\"#0000ff\",\"editorLightBulb.foreground\":\"#ddb100\",\"editorLightBulbAutoFix.foreground\":\"#007acc\",\"diffEditor.insertedTextBackground\":\"#9ccc2c40\",\"diffEditor.insertedTextBorder\":null,\"diffEditor.removedTextBackground\":\"#ff000033\",\"diffEditor.removedTextBorder\":null,\"diffEditor.insertedLineBackground\":\"#9bb95533\",\"diffEditor.removedLineBackground\":\"#ff000033\",\"editorStickyScroll.background\":\"#fbfbfb\",\"editorStickyScrollHover.background\":\"#f0f0f0\",\"editorInlayHint.background\":\"#2aa29899\",\"editorInlayHint.foreground\":\"#f0f0f0\",\"editorInlayHint.typeBackground\":\"#2aa29899\",\"editorInlayHint.typeForeground\":\"#f0f0f0\",\"editorInlayHint.parameterBackground\":\"#2aa29899\",\"editorInlayHint.parameterForeground\":\"#f0f0f0\",\"editorPane.background\":\"#fbfbfb\",\"editorGroup.emptyBackground\":null,\"editorGroup.focusedEmptyBorder\":null,\"editorGroupHeader.tabsBackground\":\"var(--sl-color-gray-6)\",\"editorGroupHeader.tabsBorder\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"editorGroupHeader.noTabsBackground\":\"#f0f0f0\",\"editorGroupHeader.border\":null,\"editorGroup.border\":\"#f0f0f0\",\"editorGroup.dropBackground\":\"#2677cb2d\",\"editorGroup.dropIntoPromptForeground\":\"#403f53\",\"editorGroup.dropIntoPromptBackground\":\"#f0f0f0\",\"editorGroup.dropIntoPromptBorder\":null,\"sideBySideEditor.horizontalBorder\":\"#f0f0f0\",\"sideBySideEditor.verticalBorder\":\"#f0f0f0\",\"scrollbar.shadow\":\"#cccccc\",\"scrollbarSlider.background\":\"#0000001a\",\"scrollbarSlider.hoverBackground\":\"#00000055\",\"scrollbarSlider.activeBackground\":\"#00000099\",\"panel.background\":\"#f0f0f0\",\"panel.border\":\"#d9d9d9\",\"panelTitle.activeBorder\":\"#424242\",\"panelTitle.activeForeground\":\"#424242\",\"panelTitle.inactiveForeground\":\"#424242bf\",\"panelSectionHeader.background\":\"#80808051\",\"terminal.background\":\"#f6f6f6\",\"widget.shadow\":\"#d9d9d9\",\"editorWidget.background\":\"#f0f0f0\",\"editorWidget.foreground\":\"#403f53\",\"editorWidget.border\":\"#d9d9d9\",\"quickInput.background\":\"#f0f0f0\",\"quickInput.foreground\":\"#403f53\",\"quickInputTitle.background\":\"#0000000f\",\"pickerGroup.foreground\":\"#403f53\",\"pickerGroup.border\":\"#d9d9d9\",\"editor.hoverHighlightBackground\":\"#339cec33\",\"editorHoverWidget.background\":\"#f0f0f0\",\"editorHoverWidget.foreground\":\"#403f53\",\"editorHoverWidget.border\":\"#d9d9d9\",\"editorHoverWidget.statusBarBackground\":\"#e4e4e4\",\"titleBar.activeBackground\":\"var(--sl-color-gray-6)\",\"titleBar.activeForeground\":\"var(--sl-color-text)\",\"titleBar.inactiveBackground\":\"#f0f0f099\",\"titleBar.inactiveForeground\":\"#33333399\",\"titleBar.border\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"toolbar.hoverBackground\":\"#b8b8b850\",\"toolbar.activeBackground\":\"#a6a6a650\",\"tab.activeBackground\":\"#f6f6f6\",\"tab.unfocusedActiveBackground\":\"#f6f6f6\",\"tab.inactiveBackground\":\"#f0f0f0\",\"tab.unfocusedInactiveBackground\":\"#f0f0f0\",\"tab.activeForeground\":\"var(--sl-color-text)\",\"tab.inactiveForeground\":\"#403f53\",\"tab.unfocusedActiveForeground\":\"#403f53b3\",\"tab.unfocusedInactiveForeground\":\"#403f5380\",\"tab.hoverBackground\":null,\"tab.unfocusedHoverBackground\":null,\"tab.hoverForeground\":null,\"tab.unfocusedHoverForeground\":null,\"tab.border\":\"#f0f0f0\",\"tab.lastPinnedBorder\":\"#a9a9a9\",\"tab.activeBorder\":\"transparent\",\"tab.unfocusedActiveBorder\":null,\"tab.activeBorderTop\":\"var(--sl-color-accent)\",\"tab.unfocusedActiveBorderTop\":null,\"tab.hoverBorder\":null,\"tab.unfocusedHoverBorder\":null,\"tab.activeModifiedBorder\":\"#2aa298\",\"tab.inactiveModifiedBorder\":\"#93a1a1\",\"tab.unfocusedActiveModifiedBorder\":\"#93a1a1\",\"tab.unfocusedInactiveModifiedBorder\":\"#93a1a1\",\"badge.background\":\"#2aa298\",\"badge.foreground\":\"#f0f0f0\",\"button.background\":\"#2aa298\",\"button.foreground\":\"#f0f0f0\",\"button.border\":null,\"button.separator\":\"#f0f0f066\",\"button.hoverBackground\":\"#22827a\",\"button.secondaryBackground\":\"#5f6a79\",\"button.secondaryForeground\":\"#ffffff\",\"button.secondaryHoverBackground\":\"#4c5561\",\"dropdown.background\":\"#f0f0f0\",\"dropdown.foreground\":\"#403f53\",\"dropdown.border\":\"#d9d9d9\",\"list.activeSelectionBackground\":\"#d3e8f8\",\"list.activeSelectionForeground\":\"#403f53\",\"tree.indentGuidesStroke\":\"#a9a9a9\",\"input.background\":\"#f0f0f0\",\"input.foreground\":\"#403f53\",\"input.placeholderForeground\":\"#93a1a1\",\"inputOption.activeBorder\":\"#2aa298\",\"inputOption.hoverBackground\":\"#b8b8b850\",\"inputOption.activeBackground\":\"#93a1a133\",\"inputOption.activeForeground\":\"#000000\",\"inputValidation.infoBackground\":\"#f0f0f0\",\"inputValidation.infoBorder\":\"#d0d0d0\",\"inputValidation.warningBackground\":\"#daaa01\",\"inputValidation.warningBorder\":\"#e0af02\",\"inputValidation.errorBackground\":\"#f76e6e\",\"inputValidation.errorBorder\":\"#de3d3b\",\"keybindingLabel.background\":\"#dddddd66\",\"keybindingLabel.foreground\":\"#555555\",\"keybindingLabel.border\":\"#cccccc66\",\"keybindingLabel.bottomBorder\":\"#bbbbbb66\",\"menu.foreground\":\"#403f53\",\"menu.background\":\"#f0f0f0\",\"menu.selectionForeground\":\"#403f53\",\"menu.selectionBackground\":\"#d3e8f8\",\"menu.separatorBackground\":\"#d4d4d4\",\"editor.snippetTabstopHighlightBackground\":\"#0a326433\",\"editor.snippetFinalTabstopHighlightBorder\":\"#0a326480\",\"terminal.ansiBlack\":\"#403f53\",\"terminal.ansiRed\":\"#de3d3b\",\"terminal.ansiGreen\":\"#08916a\",\"terminal.ansiYellow\":\"#e0af02\",\"terminal.ansiBlue\":\"#288ed7\",\"terminal.ansiMagenta\":\"#d6438a\",\"terminal.ansiCyan\":\"#2aa298\",\"terminal.ansiWhite\":\"#f0f0f0\",\"terminal.ansiBrightBlack\":\"#403f53\",\"terminal.ansiBrightRed\":\"#de3d3b\",\"terminal.ansiBrightGreen\":\"#08916a\",\"terminal.ansiBrightYellow\":\"#daaa01\",\"terminal.ansiBrightBlue\":\"#288ed7\",\"terminal.ansiBrightMagenta\":\"#d6438a\",\"terminal.ansiBrightCyan\":\"#2aa298\",\"terminal.ansiBrightWhite\":\"#f0f0f0\",\"selection.background\":\"#7a8181ad\",\"notifications.background\":\"#f0f0f0\",\"notifications.foreground\":\"#403f53\",\"notificationLink.foreground\":\"#994cc3\",\"notifications.border\":\"#cccccc\",\"notificationCenter.border\":\"#cccccc\",\"notificationToast.border\":\"#cccccc\",\"notificationCenterHeader.foreground\":\"#403f53\",\"notificationCenterHeader.background\":\"#f0f0f0\",\"input.border\":\"#d9d9d9\",\"progressBar.background\":\"#2aa298\",\"list.inactiveSelectionBackground\":\"#e0e7ea\",\"list.inactiveSelectionForeground\":\"#403f53\",\"list.focusBackground\":\"#d3e8f8\",\"list.hoverBackground\":\"#d3e8f8\",\"list.focusForeground\":\"#403f53\",\"list.hoverForeground\":\"#403f53\",\"list.highlightForeground\":\"#403f53\",\"list.errorForeground\":\"#e64d49\",\"list.warningForeground\":\"#daaa01\",\"activityBar.background\":\"#f0f0f0\",\"activityBar.foreground\":\"#403f53\",\"activityBar.dropBackground\":\"#d0d0d0\",\"activityBarBadge.background\":\"#403f53\",\"activityBarBadge.foreground\":\"#f0f0f0\",\"activityBar.border\":\"#f0f0f0\",\"sideBar.background\":\"#f0f0f0\",\"sideBar.foreground\":\"#403f53\",\"sideBarTitle.foreground\":\"#403f53\",\"sideBar.border\":\"#f0f0f0\",\"editorGroup.background\":\"#f6f6f6\",\"editorCursor.foreground\":\"#90a7b2\",\"editor.wordHighlightBackground\":\"#339cec33\",\"editor.wordHighlightStrongBackground\":\"#007dd659\",\"editor.lineHighlightBackground\":\"#f0f0f0\",\"editor.rangeHighlightBackground\":\"#7497a633\",\"editorWhitespace.foreground\":\"#d9d9d9\",\"editorIndentGuide.background\":\"#d9d9d9\",\"editorCodeLens.foreground\":\"#403f53\",\"editorBracketMatch.background\":\"#d3e8f8\",\"editorBracketMatch.border\":\"#2aa298\",\"editorError.border\":\"#fbfbfb\",\"editorWarning.border\":\"#daaa01\",\"editorGutter.addedBackground\":\"#49d0c5\",\"editorGutter.modifiedBackground\":\"#6fbef6\",\"editorGutter.deletedBackground\":\"#f76e6e\",\"editorRuler.foreground\":\"#d9d9d9\",\"editorOverviewRuler.errorForeground\":\"#e64d49\",\"editorOverviewRuler.warningForeground\":\"#daaa01\",\"editorSuggestWidget.background\":\"#f0f0f0\",\"editorSuggestWidget.foreground\":\"#403f53\",\"editorSuggestWidget.highlightForeground\":\"#403f53\",\"editorSuggestWidget.selectedBackground\":\"#d3e8f8\",\"editorSuggestWidget.border\":\"#d9d9d9\",\"debugExceptionWidget.background\":\"#f0f0f0\",\"debugExceptionWidget.border\":\"#d9d9d9\",\"editorMarkerNavigation.background\":\"#d0d0d0\",\"editorMarkerNavigationError.background\":\"#f76e6e\",\"editorMarkerNavigationWarning.background\":\"#daaa01\",\"debugToolBar.background\":\"#f0f0f0\",\"extensionButton.prominentBackground\":\"#2aa298\",\"extensionButton.prominentForeground\":\"#f0f0f0\",\"statusBar.background\":\"#f0f0f0\",\"statusBar.border\":\"#f0f0f0\",\"statusBar.debuggingBackground\":\"#f0f0f0\",\"statusBar.debuggingForeground\":\"#403f53\",\"statusBar.foreground\":\"#403f53\",\"statusBar.noFolderBackground\":\"#f0f0f0\",\"statusBar.noFolderForeground\":\"#403f53\",\"peekView.border\":\"#d9d9d9\",\"peekViewEditor.background\":\"#f6f6f6\",\"peekViewEditorGutter.background\":\"#f6f6f6\",\"peekViewEditor.matchHighlightBackground\":\"#49d0c5\",\"peekViewResult.background\":\"#f0f0f0\",\"peekViewResult.fileForeground\":\"#403f53\",\"peekViewResult.lineForeground\":\"#403f53\",\"peekViewResult.matchHighlightBackground\":\"#49d0c5\",\"peekViewResult.selectionBackground\":\"#e0e7ea\",\"peekViewResult.selectionForeground\":\"#403f53\",\"peekViewTitle.background\":\"#f0f0f0\",\"peekViewTitleLabel.foreground\":\"#403f53\",\"peekViewTitleDescription.foreground\":\"#403f53\",\"terminal.foreground\":\"#403f53\"},\"fg\":\"#403f53\",\"bg\":\"#f6f7f9\",\"semanticHighlighting\":false,\"settings\":[{\"name\":\"Changed\",\"scope\":[\"markup.changed\",\"meta.diff.header.git\",\"meta.diff.header.from-file\",\"meta.diff.header.to-file\"],\"settings\":{\"foreground\":\"#556484\"}},{\"name\":\"Deleted\",\"scope\":[\"markup.deleted.diff\"],\"settings\":{\"foreground\":\"#ae3c3afd\"}},{\"name\":\"Inserted\",\"scope\":[\"markup.inserted.diff\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Global settings\",\"settings\":{\"background\":\"#011627\",\"foreground\":\"#403f53\"}},{\"name\":\"Comment\",\"scope\":[\"comment\"],\"settings\":{\"foreground\":\"#5f636f\"}},{\"name\":\"String\",\"scope\":[\"string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"String Quoted\",\"scope\":[\"string.quoted\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Support Constant Math\",\"scope\":[\"support.constant.math\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Number\",\"scope\":[\"constant.numeric\",\"constant.character.numeric\"],\"settings\":{\"foreground\":\"#aa0982\",\"fontStyle\":\"\"}},{\"name\":\"Built-in constant\",\"scope\":[\"constant.language\",\"punctuation.definition.constant\",\"variable.other.constant\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"User-defined constant\",\"scope\":[\"constant.character\",\"constant.other\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Constant Character Escape\",\"scope\":[\"constant.character.escape\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"RegExp String\",\"scope\":[\"string.regexp\",\"string.regexp keyword.other\"],\"settings\":{\"foreground\":\"#3a688f\"}},{\"name\":\"Comma in functions\",\"scope\":[\"meta.function punctuation.separator.comma\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"Variable\",\"scope\":[\"variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Keyword\",\"scope\":[\"punctuation.accessor\",\"keyword\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage\",\"scope\":[\"storage\",\"meta.var.expr\",\"meta.class meta.method.declaration meta.var.expr storage.type.js\",\"storage.type.property.js\",\"storage.type.property.ts\",\"storage.type.property.tsx\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type.function.arrow.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Class name\",\"scope\":[\"entity.name.class\",\"meta.class entity.name.type.class\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Inherited class\",\"scope\":[\"entity.other.inherited-class\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Function name\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Meta Tag\",\"scope\":[\"punctuation.definition.tag\",\"meta.tag\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"HTML Tag names\",\"scope\":[\"entity.name.tag\",\"meta.tag.other.html\",\"meta.tag.other.js\",\"meta.tag.other.tsx\",\"entity.name.tag.tsx\",\"entity.name.tag.js\",\"entity.name.tag\",\"meta.tag.js\",\"meta.tag.tsx\",\"meta.tag.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Tag attribute\",\"scope\":[\"entity.other.attribute-name\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Entity Name Tag Custom\",\"scope\":[\"entity.name.tag.custom\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Library (function & constant)\",\"scope\":[\"support.function\",\"support.constant\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Support Constant Property Value meta\",\"scope\":[\"support.constant.meta.property-value\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Library class/type\",\"scope\":[\"support.type\",\"support.class\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Support Variable DOM\",\"scope\":[\"support.variable.dom\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Invalid\",\"scope\":[\"invalid\"],\"settings\":{\"foreground\":\"#bb2060\"}},{\"name\":\"Invalid deprecated\",\"scope\":[\"invalid.deprecated\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Keyword Operator\",\"scope\":[\"keyword.operator\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Relational\",\"scope\":[\"keyword.operator.relational\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Assignment\",\"scope\":[\"keyword.operator.assignment\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Arithmetic\",\"scope\":[\"keyword.operator.arithmetic\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Bitwise\",\"scope\":[\"keyword.operator.bitwise\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Increment\",\"scope\":[\"keyword.operator.increment\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Ternary\",\"scope\":[\"keyword.operator.ternary\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Double-Slashed Comment\",\"scope\":[\"comment.line.double-slash\"],\"settings\":{\"foreground\":\"#5d6376\"}},{\"name\":\"Object\",\"scope\":[\"object\"],\"settings\":{\"foreground\":\"#58656a\"}},{\"name\":\"Null\",\"scope\":[\"constant.language.null\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Meta Brace\",\"scope\":[\"meta.brace\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Meta Delimiter Period\",\"scope\":[\"meta.delimiter.period\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Punctuation Definition String\",\"scope\":[\"punctuation.definition.string\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Punctuation Definition String Markdown\",\"scope\":[\"punctuation.definition.string.begin.markdown\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Boolean\",\"scope\":[\"constant.language.boolean\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Object Comma\",\"scope\":[\"object.comma\"],\"settings\":{\"foreground\":\"#646464\"}},{\"name\":\"Variable Parameter Function\",\"scope\":[\"variable.parameter.function\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Support Type Property Name & entity name tags\",\"scope\":[\"support.type.vendor.property-name\",\"support.constant.vendor.property-value\",\"support.type.property-name\",\"meta.property-list entity.name.tag\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Entity Name tag reference in stylesheets\",\"scope\":[\"meta.property-list entity.name.tag.reference\"],\"settings\":{\"foreground\":\"#286d70\"}},{\"name\":\"Constant Other Color RGB Value Punctuation Definition Constant\",\"scope\":[\"constant.other.color.rgb-value punctuation.definition.constant\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Constant Other Color\",\"scope\":[\"constant.other.color\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Keyword Other Unit\",\"scope\":[\"keyword.other.unit\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Meta Selector\",\"scope\":[\"meta.selector\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Entity Other Attribute Name Id\",\"scope\":[\"entity.other.attribute-name.id\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Meta Property Name\",\"scope\":[\"meta.property-name\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Doctypes\",\"scope\":[\"entity.name.tag.doctype\",\"meta.tag.sgml.doctype\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Punctuation Definition Parameters\",\"scope\":[\"punctuation.definition.parameters\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Keyword Control Operator\",\"scope\":[\"keyword.control.operator\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Keyword Operator Logical\",\"scope\":[\"keyword.operator.logical\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"\"}},{\"name\":\"Variable Instances\",\"scope\":[\"variable.instance\",\"variable.other.instance\",\"variable.readwrite.instance\",\"variable.other.readwrite.instance\",\"variable.other.property\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Variable Property Other object property\",\"scope\":[\"variable.other.object.property\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Variable Property Other object\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Entity Name Function\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Keyword Operator Comparison, imports, returns and Keyword Operator Ruby\",\"scope\":[\"keyword.operator.comparison\",\"keyword.control.flow.js\",\"keyword.control.flow.ts\",\"keyword.control.flow.tsx\",\"keyword.control.ruby\",\"keyword.control.module.ruby\",\"keyword.control.class.ruby\",\"keyword.control.def.ruby\",\"keyword.control.loop.js\",\"keyword.control.loop.ts\",\"keyword.control.import.js\",\"keyword.control.import.ts\",\"keyword.control.import.tsx\",\"keyword.control.from.js\",\"keyword.control.from.ts\",\"keyword.control.from.tsx\",\"keyword.operator.instanceof.js\",\"keyword.operator.expression.instanceof.ts\",\"keyword.operator.expression.instanceof.tsx\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Control Conditional\",\"scope\":[\"keyword.control.conditional.js\",\"keyword.control.conditional.ts\",\"keyword.control.switch.js\",\"keyword.control.switch.ts\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"\"}},{\"name\":\"Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords\",\"scope\":[\"support.constant\",\"keyword.other.special-method\",\"keyword.other.new\",\"keyword.other.debugger\",\"keyword.control\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Support Function\",\"scope\":[\"support.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Invalid Broken\",\"scope\":[\"invalid.broken\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Invalid Unimplemented\",\"scope\":[\"invalid.unimplemented\"],\"settings\":{\"foreground\":\"#486e26\"}},{\"name\":\"Invalid Illegal\",\"scope\":[\"invalid.illegal\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Language Variable\",\"scope\":[\"variable.language\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Support Variable Property\",\"scope\":[\"support.variable.property\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Variable Function\",\"scope\":[\"variable.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variable Interpolation\",\"scope\":[\"variable.interpolation\"],\"settings\":{\"foreground\":\"#a64348\"}},{\"name\":\"Meta Function Call\",\"scope\":[\"meta.function-call\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Punctuation Section Embedded\",\"scope\":[\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Punctuation Tweaks\",\"scope\":[\"punctuation.terminator.expression\",\"punctuation.definition.arguments\",\"punctuation.definition.array\",\"punctuation.section.array\",\"meta.array\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"More Punctuation Tweaks\",\"scope\":[\"punctuation.definition.list.begin\",\"punctuation.definition.list.end\",\"punctuation.separator.arguments\",\"punctuation.definition.list\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Template Strings\",\"scope\":[\"string.template meta.template.expression\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Backticks(``) in Template Strings\",\"scope\":[\"string.template punctuation.definition.string\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Italics\",\"scope\":[\"italic\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"italic\"}},{\"name\":\"Bold\",\"scope\":[\"bold\"],\"settings\":{\"foreground\":\"#3b61b0\",\"fontStyle\":\"bold\"}},{\"name\":\"Quote\",\"scope\":[\"quote\"],\"settings\":{\"foreground\":\"#5c6285\"}},{\"name\":\"Raw Code\",\"scope\":[\"raw\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"CoffeeScript Variable Assignment\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#186e73\"}},{\"name\":\"CoffeeScript Parameter Function\",\"scope\":[\"variable.parameter.function.coffee\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"CoffeeScript Assignments\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"C# Readwrite Variables\",\"scope\":[\"variable.other.readwrite.cs\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"C# Classes & Storage types\",\"scope\":[\"entity.name.type.class.cs\",\"storage.type.cs\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"C# Namespaces\",\"scope\":[\"entity.name.type.namespace.cs\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Tag names in Stylesheets\",\"scope\":[\"entity.name.tag.css\",\"entity.name.tag.less\",\"entity.name.tag.custom.css\",\"support.constant.property-value.css\"],\"settings\":{\"foreground\":\"#984e4d\",\"fontStyle\":\"\"}},{\"name\":\"Wildcard(*) selector in Stylesheets\",\"scope\":[\"entity.name.tag.wildcard.css\",\"entity.name.tag.wildcard.less\",\"entity.name.tag.wildcard.scss\",\"entity.name.tag.wildcard.sass\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"CSS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Attribute Name for CSS\",\"scope\":[\"meta.attribute-selector.css entity.other.attribute-name.attribute\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Elixir Classes\",\"scope\":[\"source.elixir support.type.elixir\",\"source.elixir meta.module.elixir entity.name.class.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Functions\",\"scope\":[\"source.elixir entity.name.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Constants\",\"scope\":[\"source.elixir constant.other.symbol.elixir\",\"source.elixir constant.other.keywords.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir String Punctuations\",\"scope\":[\"source.elixir punctuation.definition.string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir\",\"scope\":[\"source.elixir variable.other.readwrite.module.elixir\",\"source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Binary Punctuations\",\"scope\":[\"source.elixir .punctuation.binary.elixir\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Closure Constant Keyword\",\"scope\":[\"constant.keyword.clojure\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Go Function Calls\",\"scope\":[\"source.go meta.function-call.go\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Go Keywords\",\"scope\":[\"source.go keyword.package.go\",\"source.go keyword.import.go\",\"source.go keyword.function.go\",\"source.go keyword.type.go\",\"source.go keyword.struct.go\",\"source.go keyword.interface.go\",\"source.go keyword.const.go\",\"source.go keyword.var.go\",\"source.go keyword.map.go\",\"source.go keyword.channel.go\",\"source.go keyword.control.go\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Go Constants e.g. nil, string format (%s, %d, etc.)\",\"scope\":[\"source.go constant.language.go\",\"source.go constant.other.placeholder.go\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"C++ Functions\",\"scope\":[\"entity.name.function.preprocessor.cpp\",\"entity.scope.name.cpp\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"C++ Meta Namespace\",\"scope\":[\"meta.namespace-block.cpp\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"C++ Language Primitive Storage\",\"scope\":[\"storage.type.language.primitive.cpp\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"C++ Preprocessor Macro\",\"scope\":[\"meta.preprocessor.macro.cpp\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"C++ Variable Parameter\",\"scope\":[\"variable.parameter\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Powershell Variables\",\"scope\":[\"variable.other.readwrite.powershell\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Powershell Function\",\"scope\":[\"support.function.powershell\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"ID Attribute Name in HTML\",\"scope\":[\"entity.other.attribute-name.id.html\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"HTML Punctuation Definition Tag\",\"scope\":[\"punctuation.definition.tag.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"HTML Doctype\",\"scope\":[\"meta.tag.sgml.doctype.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"JavaScript Classes\",\"scope\":[\"meta.class entity.name.type.class.js\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"JavaScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.js\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"JavaScript Terminator\",\"scope\":[\"terminator.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Meta Punctuation Definition\",\"scope\":[\"meta.js punctuation.definition.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Entity Names in Code Documentations\",\"scope\":[\"entity.name.type.instance.jsdoc\",\"entity.name.type.instance.phpdoc\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"Other Variables in Code Documentations\",\"scope\":[\"variable.other.jsdoc\",\"variable.other.phpdoc\"],\"settings\":{\"foreground\":\"#3e697c\"}},{\"name\":\"JavaScript module imports and exports\",\"scope\":[\"variable.other.meta.import.js\",\"meta.import.js variable.other\",\"variable.other.meta.export.js\",\"meta.export.js variable.other\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Variable Parameter Function\",\"scope\":[\"variable.parameter.function.js\"],\"settings\":{\"foreground\":\"#555ea2\"}},{\"name\":\"JavaScript[React] Variable Other Object\",\"scope\":[\"variable.other.object.js\",\"variable.other.object.jsx\",\"variable.object.property.js\",\"variable.object.property.jsx\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Variables\",\"scope\":[\"variable.js\",\"variable.other.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Entity Name Type\",\"scope\":[\"entity.name.type.js\",\"entity.name.type.module.js\"],\"settings\":{\"foreground\":\"#111111\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Support Classes\",\"scope\":[\"support.class.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JSON Property Names\",\"scope\":[\"support.type.property-name.json\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"JSON Support Constants\",\"scope\":[\"support.constant.json\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"JSON Property values (string)\",\"scope\":[\"meta.structure.dictionary.value.json string.quoted.double\"],\"settings\":{\"foreground\":\"#7c5686\"}},{\"name\":\"Strings in JSON values\",\"scope\":[\"string.quoted.double.json punctuation.definition.string.json\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Specific JSON Property values like null\",\"scope\":[\"meta.structure.dictionary.json meta.structure.dictionary.value constant.language\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"JavaScript Other Variable\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Ruby Variables\",\"scope\":[\"variable.other.ruby\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Ruby Class\",\"scope\":[\"entity.name.type.class.ruby\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Ruby Hashkeys\",\"scope\":[\"constant.language.symbol.hashkey.ruby\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Ruby Symbols\",\"scope\":[\"constant.language.symbol.ruby\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"LESS Tag names\",\"scope\":[\"entity.name.tag.less\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"LESS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Attribute Name for LESS\",\"scope\":[\"meta.attribute-selector.less entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Markdown Headings\",\"scope\":[\"markup.heading.markdown\",\"markup.heading.setext.1.markdown\",\"markup.heading.setext.2.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown Italics\",\"scope\":[\"markup.italic.markdown\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"italic\"}},{\"name\":\"Markdown Bold\",\"scope\":[\"markup.bold.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\",\"fontStyle\":\"bold\"}},{\"name\":\"Markdown Quote + others\",\"scope\":[\"markup.quote.markdown\"],\"settings\":{\"foreground\":\"#5c6285\"}},{\"name\":\"Markdown Raw Code + others\",\"scope\":[\"markup.inline.raw.markdown\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Markdown Links\",\"scope\":[\"markup.underline.link.markdown\",\"markup.underline.link.image.markdown\"],\"settings\":{\"foreground\":\"#954f5a\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Link Title and Description\",\"scope\":[\"string.other.link.title.markdown\",\"string.other.link.description.markdown\"],\"settings\":{\"foreground\":\"#403f53\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Punctuation\",\"scope\":[\"punctuation.definition.string.markdown\",\"punctuation.definition.string.begin.markdown\",\"punctuation.definition.string.end.markdown\",\"meta.link.inline.markdown punctuation.definition.string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown MetaData Punctuation\",\"scope\":[\"punctuation.definition.metadata.markdown\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Markdown List Punctuation\",\"scope\":[\"beginning.punctuation.definition.list.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown Inline Raw String\",\"scope\":[\"markup.inline.raw.string.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"PHP Variables\",\"scope\":[\"variable.other.php\",\"variable.other.property.php\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Support Classes in PHP\",\"scope\":[\"support.class.php\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Punctuations in PHP function calls\",\"scope\":[\"meta.function-call.php punctuation\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"PHP Global Variables\",\"scope\":[\"variable.other.global.php\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Declaration Punctuation in PHP Global Variables\",\"scope\":[\"variable.other.global.php punctuation.definition.variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Language Constants in Python\",\"scope\":[\"constant.language.python\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Python Function Parameter and Arguments\",\"scope\":[\"variable.parameter.function.python\",\"meta.function-call.arguments.python\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Python Function Call\",\"scope\":[\"meta.function-call.python\",\"meta.function-call.generic.python\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Punctuations in Python\",\"scope\":[\"punctuation.python\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Decorator Functions in Python\",\"scope\":[\"entity.name.function.decorator.python\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Python Language Variable\",\"scope\":[\"source.python variable.language.special\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Python import control keyword\",\"scope\":[\"keyword.control\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"SCSS Variable\",\"scope\":[\"variable.scss\",\"variable.sass\",\"variable.parameter.url.scss\",\"variable.parameter.url.sass\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Attribute Name for SASS\",\"scope\":[\"meta.attribute-selector.scss entity.other.attribute-name.attribute\",\"meta.attribute-selector.sass entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Tag names in SASS\",\"scope\":[\"entity.name.tag.scss\",\"entity.name.tag.sass\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"SASS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.scss\",\"keyword.other.unit.sass\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"TypeScript[React] Variables and Object Properties\",\"scope\":[\"variable.other.readwrite.alias.ts\",\"variable.other.readwrite.alias.tsx\",\"variable.other.readwrite.ts\",\"variable.other.readwrite.tsx\",\"variable.other.object.ts\",\"variable.other.object.tsx\",\"variable.object.property.ts\",\"variable.object.property.tsx\",\"variable.other.ts\",\"variable.other.tsx\",\"variable.tsx\",\"variable.ts\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript[React] Entity Name Types\",\"scope\":[\"entity.name.type.ts\",\"entity.name.type.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript[React] Node Classes\",\"scope\":[\"support.class.node.ts\",\"support.class.node.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"TypeScript[React] Entity Name Types as Parameters\",\"scope\":[\"meta.type.parameters.ts entity.name.type\",\"meta.type.parameters.tsx entity.name.type\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"TypeScript[React] Import/Export Punctuations\",\"scope\":[\"meta.import.ts punctuation.definition.block\",\"meta.import.tsx punctuation.definition.block\",\"meta.export.ts punctuation.definition.block\",\"meta.export.tsx punctuation.definition.block\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.decorator punctuation.decorator.ts\",\"meta.decorator punctuation.decorator.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.tag.js meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"YAML Entity Name Tags\",\"scope\":[\"entity.name.tag.yaml\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"JavaScript Variable Other ReadWrite\",\"scope\":[\"variable.other.readwrite.js\",\"variable.parameter\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Support Class Component\",\"scope\":[\"support.class.component.js\",\"support.class.component.tsx\"],\"settings\":{\"foreground\":\"#aa0982\",\"fontStyle\":\"\"}},{\"name\":\"Text nested in React tags\",\"scope\":[\"meta.jsx.children\",\"meta.jsx.children.js\",\"meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript Classes\",\"scope\":[\"meta.class entity.name.type.class.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript Entity Name Type\",\"scope\":[\"entity.name.type.tsx\",\"entity.name.type.module.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript Class Variable Keyword\",\"scope\":[\"meta.class.ts meta.var.expr.ts storage.type.ts\",\"meta.class.tsx meta.var.expr.tsx storage.type.tsx\"],\"settings\":{\"foreground\":\"#76578b\"}},{\"name\":\"TypeScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.ts\",\"meta.method.declaration storage.type.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"normalize font style of certain components\",\"scope\":[\"meta.property-list.css meta.property-value.css variable.other.less\",\"meta.property-list.scss variable.scss\",\"meta.property-list.sass variable.sass\",\"meta.brace\",\"keyword.operator.operator\",\"keyword.operator.or.regexp\",\"keyword.operator.expression.in\",\"keyword.operator.relational\",\"keyword.operator.assignment\",\"keyword.operator.comparison\",\"keyword.operator.type\",\"keyword.operator\",\"keyword\",\"punctuation.definition.string\",\"punctuation\",\"variable.other.readwrite.js\",\"storage.type\",\"source.css\",\"string.quoted\"],\"settings\":{\"fontStyle\":\"\"}}],\"styleOverrides\":{\"frames\":{\"editorBackground\":\"var(--sl-color-gray-7)\",\"terminalBackground\":\"var(--sl-color-gray-7)\",\"editorActiveTabBackground\":\"var(--sl-color-gray-7)\",\"terminalTitlebarDotsForeground\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"terminalTitlebarDotsOpacity\":\"0.75\",\"inlineButtonForeground\":\"var(--sl-color-text)\",\"frameBoxShadowCssValue\":\"none\"},\"textMarkers\":{\"markBackground\":\"#0000001a\",\"markBorderColor\":\"#00000055\"}}}],\"defaultLocale\":\"en\",\"cascadeLayer\":\"starlight.components\",\"styleOverrides\":{\"borderRadius\":\"0px\",\"borderWidth\":\"1px\",\"codePaddingBlock\":\"0.75rem\",\"codePaddingInline\":\"1rem\",\"codeFontFamily\":\"var(--__sl-font-mono)\",\"codeFontSize\":\"var(--sl-text-code)\",\"codeLineHeight\":\"var(--sl-line-height)\",\"uiFontFamily\":\"var(--__sl-font)\",\"textMarkers\":{\"lineDiffIndicatorMarginLeft\":\"0.25rem\",\"defaultChroma\":\"45\",\"backgroundOpacity\":\"60%\"}},\"plugins\":[{\"name\":\"Starlight Plugin\",\"hooks\":{}},{\"name\":\"astro-expressive-code\",\"hooks\":{}}]}]],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true,\"allowedDomains\":[],\"actionBodySizeLimit\":1048576},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"headingIdCompat\":false,\"preserveScriptOrder\":false,\"liveContentCollections\":false,\"csp\":false,\"staticImportMetaEnv\":false,\"chromeDevtoolsWorkspace\":false,\"failOnPrerenderConflict\":false,\"svgo\":false},\"legacy\":{\"collections\":false},\"prefetch\":{\"prefetchAll\":true},\"i18n\":{\"defaultLocale\":\"en\",\"locales\":[\"en\"],\"routing\":{\"prefixDefaultLocale\":false,\"redirectToDefaultLocale\":false,\"fallbackType\":\"redirect\"}}}","docs",["Map",11,12,27,28,47,48,66,67,89,90,108,109,127,128,149,150],"index",{"id":11,"data":13,"filePath":25,"digest":26,"deferredRender":16},{"title":14,"description":15,"editUrl":16,"head":17,"template":18,"hero":19,"sidebar":22,"pagefind":16,"draft":23},"CreateHer Fest","Let's build some sample applications!",true,[],"splash",{"tagline":20,"actions":21},"DIALED IN! Answer calls in WebXR.",[],{"hidden":23,"attrs":24},false,{},"src/content/docs/index.mdx","5742d2bb91f1973b","02_setup_application",{"id":27,"data":29,"body":36,"filePath":37,"digest":38,"rendered":39},{"title":30,"description":31,"editUrl":16,"head":32,"template":33,"sidebar":34,"pagefind":16,"draft":23},"Setup Application","Create an application.",[],"doc",{"hidden":23,"attrs":35},{},"> Note: Please make sure to redeem the coupon code to your Vonage account's \u003Ca href=\"https://dashboard.vonage.com/coupons\" target=\"_blank\">dashboard\u003C/a> before continuing. It is needed to purchase a phone number.\n\nIn the terminal below, you should see a set up script running asking for your `API key`. Complete the steps in the set up script. This will create an Application with Voice functionality, purchase a phone number, and create the needed Webhook endpoints.\n\n> Note: You can get your credentials in the \u003Ca href=\"https://dashboard.vonage.com/settings\" target=\"_blank\">Vonage dashboard Settings Page\u003C/a>\n\nIf successful, you should see `APPLICATION READY` with a URL. Click the link to open in a new window or tab.","src/content/docs/02_Setup_Application.md","41ac2dedeb3ab62b",{"html":40,"metadata":41},"\u003Cblockquote>\n\u003Cp>Note: Please make sure to redeem the coupon code to your Vonage account’s \u003Ca href=\"https://dashboard.vonage.com/coupons\" target=\"_blank\">dashboard\u003C/a> before continuing. It is needed to purchase a phone number.\u003C/p>\n\u003C/blockquote>\n\u003Cp>In the terminal below, you should see a set up script running asking for your \u003Ccode dir=\"auto\">API key\u003C/code>. Complete the steps in the set up script. This will create an Application with Voice functionality, purchase a phone number, and create the needed Webhook endpoints.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Note: You can get your credentials in the \u003Ca href=\"https://dashboard.vonage.com/settings\" target=\"_blank\">Vonage dashboard Settings Page\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cp>If successful, you should see \u003Ccode dir=\"auto\">APPLICATION READY\u003C/code> with a URL. Click the link to open in a new window or tab.\u003C/p>",{"headings":42,"localImagePaths":43,"remoteImagePaths":44,"frontmatter":45,"imagePaths":46},[],[],[],{"title":30,"description":31},[],"01_create_account",{"id":47,"data":49,"body":55,"filePath":56,"digest":57,"rendered":58},{"title":50,"description":51,"editUrl":16,"head":52,"template":33,"sidebar":53,"pagefind":16,"draft":23},"Create an Account","Create a Vonage account.",[],{"hidden":23,"attrs":54},{},"First, a Vonage account is needed to get the credentials to set up this workshop applications. You can sign up for your account here: \u003Ca href=\"https://dashboard.vonage.com\" target=\"_blank\">Vonage dashboard\u003C/a>\n\nHere's a coupon to add money to your account:\n\nIf your account is in US dollars:\n\n```html\nTorcWebUS2026\n```\n\nIf your account is in Euros:\n\n```html\nTorcWebEUR2026\n```\n\n> Note: Make sure to copy your API Key and API Secret somewhere. We will need it in the next step.","src/content/docs/01_Create_Account.md","0434ab7976c6a491",{"html":59,"metadata":60},"\u003Cp>First, a Vonage account is needed to get the credentials to set up this workshop applications. You can sign up for your account here: \u003Ca href=\"https://dashboard.vonage.com\" target=\"_blank\">Vonage dashboard\u003C/a>\u003C/p>\n\u003Cp>Here’s a coupon to add money to your account:\u003C/p>\n\u003Cp>If your account is in US dollars:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">TorcWebUS2026\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"TorcWebUS2026\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>If your account is in Euros:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">TorcWebEUR2026\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"TorcWebEUR2026\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Note: Make sure to copy your API Key and API Secret somewhere. We will need it in the next step.\u003C/p>\n\u003C/blockquote>",{"headings":61,"localImagePaths":62,"remoteImagePaths":63,"frontmatter":64,"imagePaths":65},[],[],[],{"title":50,"description":51},[],"03_add_client_sdk",{"id":66,"data":68,"body":74,"filePath":75,"digest":76,"rendered":77},{"title":69,"description":70,"editUrl":16,"head":71,"template":33,"sidebar":72,"pagefind":16,"draft":23},"Add Client SDK","Add Vonage Client SDK to index.html",[],{"hidden":23,"attrs":73},{},"We'll be creating a WebXR application using \u003Ca href=\"https://xrblocks.github.io\" target=\"_blank\">XR Blocks\u003C/a> that can answer phone calls.\n\nThe following code will be placed in the `index.html` file.\n\nFirst, we will need to load the Vonage Client SDK from a CDN (`\u003C!-- ⌄⌄⌄ Load the Vonage Client SDK ⌄⌄⌄ -->`):\n```html\n\u003Cscript src=\"https://cdn.jsdelivr.net/npm/@vonage/client-sdk@latest/dist/vonageClientSDK.min.js\">\u003C/script>\n```\n\n> Note: You can also install the Client SDK and point to the nodes module folder if you are using a bundler.\n\n## That's it for the HTML!\n\nEverything else will be handled by XR Blocks.","src/content/docs/03_Add_Client_SDK.md","77c79f191f661eb3",{"html":78,"metadata":79},"\u003Cp>We’ll be creating a WebXR application using \u003Ca href=\"https://xrblocks.github.io\" target=\"_blank\">XR Blocks\u003C/a> that can answer phone calls.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">index.html\u003C/code> file.\u003C/p>\n\u003Cp>First, we will need to load the Vonage Client SDK from a CDN (\u003Ccode dir=\"auto\"><!-- ⌄⌄⌄ Load the Vonage Client SDK ⌄⌄⌄ -->\u003C/code>):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">script\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">src\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://cdn.jsdelivr.net/npm/@vonage/client-sdk@latest/dist/vonageClientSDK.min.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\">></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">script\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cscript src="https://cdn.jsdelivr.net/npm/@vonage/client-sdk@latest/dist/vonageClientSDK.min.js">\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Note: You can also install the Client SDK and point to the nodes module folder if you are using a bundler.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"thats-it-for-the-html\">That’s it for the HTML!\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#thats-it-for-the-html\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “That’s it for the HTML!”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Everything else will be handled by XR Blocks.\u003C/p>",{"headings":80,"localImagePaths":85,"remoteImagePaths":86,"frontmatter":87,"imagePaths":88},[81],{"depth":82,"slug":83,"text":84},2,"thats-it-for-the-html","That’s it for the HTML!",[],[],{"title":69,"description":70},[],"04_vonage_call_panel",{"id":89,"data":91,"body":97,"filePath":98,"digest":99,"rendered":100},{"title":92,"description":93,"editUrl":16,"head":94,"template":33,"sidebar":95,"pagefind":16,"draft":23},"Vonage Call Panel","Create XR Blocks UI to answer phone calls",[],{"hidden":23,"attrs":96},{},"Now, we'll be creating the UI.\n\nTo recieve phone calls via the Vonage Voice API using the XR Blocks library's \u003Ca href=\"https://xrblocks.github.io/docs/api/classes/SpatialPanel/\" target=\"_blank\">SpatialPanel Class\u003C/a>.\n\nTo show the 3D Avatar for the caller, we will use the \u003Ca href=\"https://xrblocks.github.io/docs/manual/Lipsync/\" target=\"_blank\">Lipsync (Addon)\u003C/a>.\n\nThe Vonage Voice Client SDK's \u003Ca href=\"https://developer.vonage.com/en/vonage-client-sdk/in-app-voice/guides/say-call\" target=\"_blank\">Text to Speech\u003C/a> will be used to send the quick replies and typed messages into the call.\n\nThe virtual keyboard that allows us to type those messages will come from the \u003Ca href=\"https://xrblocks.github.io/docs/manual/UI/#virtual-keyboard-addon\" target=\"_blank\">Virtual Keyboard (Addon)\u003C/a>.\n\nThe following code will be placed in the `VonageAudioCall.js` file.\n\nFirst, we will set the Quick Replies that the user can send into the call.\nFind `// ⌄⌄⌄ Set Quick Replies ⌄⌄⌄` and add this code:\n\n```js\nconst QUICK_REPLIES = [\n { label: \"Meeting\", message: \"In a meeting, I'll call you back.\" },\n { label: \"Talk Later\", message: \"Can't talk right now. I'll talk later.\" },\n { label: \"OMW!\", message: \"On my way! Talk soon.\" },\n { label: \"5 Mins\", message: \"Call you back in 5 minutes.\" },\n];\n```\n\nLet's initiate the constructor for our panel with some variables:\n`// ⌄⌄⌄ Create constructor ⌄⌄⌄`\n\n```js\nconstructor() {\n super();\n this.token = '';\n this.client = new vonageClientSDK.VonageClient();\n this.callId = null;\n // Keep a reference to the panel so we can destroy it later\n this.panel = null;\n this.statusText = null;\n this.userName = \"XR_User_1\";\n this.grid = null;\n this.controlRow = null;\n this.puppetHead = null;\n this.face = null;\n this.mouth = null;\n this._camWorld = new THREE.Vector3();\n this._headWorld = new THREE.Vector3();\n this.replyPanel = null;\n this.typedTextView = null;\n this._currentTypedText = '';\n this.keyboard = null;\n}\n```\n\nHere's the function to create an Avatar and add the MediaStream for the LipSync feature: `// ⌄⌄⌄ Create 3D Avatar ⌄⌄⌄`\n\n```js\n_createAvatar(stream) {\n // Safety: don't create a second avatar if one already exists\n if (this.puppetHead) return;\n\n console.log(\"Creating lipsync avatar...\");\n\n const faceR = 0.1;\n\n const head = new THREE.Group();\n // Position: in front of the user, roughly at face height\n head.position.set(0, xb.user.height, -1.2);\n\n // --- Sphere face mesh ---\n const faceGeom = new THREE.SphereGeometry(faceR, 32, 24);\n const faceMat = new THREE.MeshStandardMaterial({\n color: 0xf2d4b3,\n roughness: 0.6,\n metalness: 0.05,\n });\n const faceMesh = new THREE.Mesh(faceGeom, faceMat);\n head.add(faceMesh);\n\n this.face = new xb.StylizedFace({ showEyes: true });\n head.add(this.face);\n\n this.mouth = new LipsyncMouth(stream, { target: this.face });\n head.add(this.mouth);\n\n this.puppetHead = head;\n this.add(head);\n}\n```\n\nThis function will remove the 3D Avatar when the call is over:\n`// ⌄⌄⌄ Remove 3D Avatar ⌄⌄⌄`\n\n```js\n_removeAvatar() {\n if (!this.puppetHead) return;\n\n console.log(\"Removing lipsync avatar...\");\n\n if (this.mouth) {\n // Detach from the head group before nulling the reference\n this.mouth.parent?.remove(this.mouth);\n this.mouth = null;\n }\n\n if (this.face) {\n this.face.parent?.remove(this.face);\n // dispose() frees the underlying canvas/texture to avoid memory leaks\n this.face.dispose();\n this.face = null;\n }\n\n this.remove(this.puppetHead);\n this.puppetHead = null;\n}\n```\n\nHere's the function to create the panel:\n`// ⌄⌄⌄ Create Call panel ⌄⌄⌄`\n\n```js\n_createCallPanel(callerName) {\n // SAFETY: If a panel already exists, don't create another one.\n if (this.panel) return;\n\n console.log(\"Creating Call UI...\");\n\n // 1. Create the Panel\n this.panel = new xb.SpatialPanel({ backgroundColor: '#2b2b2baa' });\n this.panel.position.set(\n 0,\n xb.user.height - 0.5,\n -xb.user.objectDistance\n );\n\n this.add(this.panel);\n\n this.grid = this.panel.addGrid();\n\n // 2. Status Text\n this.statusText = this.grid.addRow({ weight: 0.7 }).addText({\n text: `Incoming call from ${callerName}...`,\n fontColor: '#ffffff',\n fontSize: 0.08,\n });\n\n this.updateControlRow('INCOMING');\n}\n```\n\nFunction to update the call control section:\n`// ⌄⌄⌄ Update Call controls ⌄⌄⌄`\n\n```js\nupdateControlRow(state) {\n if (!this.grid) return;\n\n // 1. Remove the existing row if it exists\n if (this.controlRow) {\n this.grid.remove(this.controlRow);\n this.controlRow = null;\n this.grid.resetLayout();\n }\n\n // 2. Create a fresh row. It will naturally append below the Status Text.\n // We give it the full remaining weight (0.3 relative to the panel, or flexible)\n this.controlRow = this.grid.addRow({ weight: 0.3 });\n\n if (state === 'INCOMING') {\n // --- ANSWER BUTTON ---\n const answerBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({\n text: 'call',\n fontSize: 0.5,\n backgroundColor: '#00ff00'\n });\n answerBtn.onTriggered = () => this._onAnswer();\n\n // --- REJECT BUTTON ---\n const rejectBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({\n text: 'call_end',\n fontSize: 0.5,\n backgroundColor: '#ff0000'\n });\n rejectBtn.onTriggered = () => this._onReject();\n\n } else if (state === 'CONNECTED') {\n // --- HANGUP BUTTON ---\n // This is a fresh row, so layouts will calculate correctly\n const hangupBtn = this.controlRow.addCol({ weight: 1 }).addIconButton({\n text: 'call_end',\n fontSize: 0.5,\n backgroundColor: '#ff0000'\n });\n hangupBtn.onTriggered = () => this._onHangup();\n }\n\n // 3. Force layout update\n this.panel.updateLayouts();\n}\n```\n\nThis function will remove the panel once the call is over:\n`// ⌄⌄⌄ Remove Call panel ⌄⌄⌄`\n\n```js\n_removeCallPanel() {\n if (this.panel) {\n console.log(\"Destroying Call UI...\");\n this.remove(this.panel);\n this.panel = null;\n this.grid = null;\n this.statusText = null;\n this.controlRow = null;\n }\n this._removeReplyPanel();\n}\n```\n\nNow, let's add the Virtual Keyboard that will allow us to send text messages that will be spoken into the call.\n\nHere's the code to show the Keyboard:\n`// ⌄⌄⌄ Show Virtual Keyboard ⌄⌄⌄`\n\n```js\n_showKeyboard() {\n if (this.keyboard) return;\n\n this.keyboard = new Keyboard();\n // Position it below and aligned with the reply panel\n this.keyboard.position.set(\n 0,\n xb.user.height - 1.35,\n -xb.user.objectDistance + 1\n );\n this.add(this.keyboard);\n\n // Update the display on every keystroke\n this.keyboard.onTextChanged = (text) => {\n this._currentTypedText = text;\n if (this.typedTextView) {\n this.typedTextView.text = text.length > 0 ? text : 'Tap to type...';\n }\n };\n\n // Enter key sends immediately — same as tapping the Send button\n this.keyboard.onEnterPressed = (text) => {\n this._sendTypedText();\n };\n}\n```\n\nIf we want to hide the Keyboard, here's the code:\n`// ⌄⌄⌄ Hide Virtual Keyboard ⌄⌄⌄`\n\n```js\n_hideKeyboard() {\n if (!this.keyboard) return;\n this.remove(this.keyboard);\n this.keyboard = null;\n}\n```\n\nTo toggle between showing and hidding the keyboard, we have this code:\n`// ⌄⌄⌄ Toggle Virtual Keyboard ⌄⌄⌄`\n\n```js\n_toggleKeyboard() {\n this.keyboard ? this._hideKeyboard() : this._showKeyboard();\n}\n```\n\nLet's create the functions that will send the text to be said into the call just in case we can't talk at that moment.\n\nTo send the Quick Replies that we set before:\n`// ⌄⌄⌄ Send Quick Reply ⌄⌄⌄`\n\n```js\n_sendQuickReply(message) {\n if (!this.callId) return;\n console.log(`Sending quick reply: \"${message}\"`);\n\n // Give the user immediate visual feedback in the status bar\n if (this.statusText) this.statusText.text = 'Sending...';\n\n this.client.say(this.callId, message)\n .then(() => {\n console.log('Quick reply sent successfully.');\n if (this.statusText) this.statusText.text = `Sent: \"${message}\"`;\n })\n .catch(err => {\n console.error('say() error:', err);\n if (this.statusText) this.statusText.text = 'Failed to send message.';\n });\n}\n```\n\nIn the case we want to carry on the conversation but maybe can't speak (ie in a public space), we can send custom text:\n`// ⌄⌄⌄ Send Custom Text ⌄⌄⌄`\n\n```js\n_sendTypedText() {\n const text = this._currentTypedText.trim();\n if (!text) return;\n if (!this.callId) return;\n\n console.log(`Sending typed text: \"${text}\"`);\n if (this.statusText) this.statusText.text = 'Sending...';\n\n this.client.say(this.callId, text)\n .then(() => {\n console.log('Typed text sent successfully.');\n if (this.statusText) this.statusText.text = `Sent: \"${text}\"`;\n\n // Clear the keyboard buffer and reset the display\n if (this.keyboard) this.keyboard.setText('');\n this._currentTypedText = '';\n if (this.typedTextView) this.typedTextView.text = 'Tap to type...';\n })\n .catch(err => {\n console.error('say() error:', err);\n if (this.statusText) this.statusText.text = 'Failed to send message.';\n });\n}\n```\n\nHere we will create the Reply panel that will hold all the way we can send a text message into the call:\n`// ⌄⌄⌄ Create Reply panel ⌄⌄⌄`\n\n```js\n_createReplyPanel() {\n if (this.replyPanel) return;\n\n this.replyPanel = new xb.SpatialPanel({\n backgroundColor: '#1a1a2ecc',\n width: .75,\n height: 0.9,\n });\n // Offset to the right so it sits beside the main call panel\n this.replyPanel.position.set(\n 0.8,\n xb.user.height - 0.5,\n -xb.user.objectDistance\n );\n this.add(this.replyPanel);\n\n const grid = this.replyPanel.addGrid();\n\n grid.addRow({ weight: 0.06 }).addText({\n text: 'Quick Replies',\n fontColor: '#9b9bff',\n fontSize: 0.055,\n });\n\n const pairs = [\n QUICK_REPLIES.slice(0, 2), // [ Meeting, Talk Later ]\n QUICK_REPLIES.slice(2, 4), // [ OMW!, 5 Mins ]\n ];\n\n pairs.forEach(pair => {\n const row = grid.addRow({ weight: 0.20 });\n pair.forEach(({ label, message }) => {\n const btn = row.addCol({ weight: 0.5 }).addTextButton({\n text: label,\n fontSize: 0.35,\n backgroundColor: '#2e2e50',\n fontColor: '#ffffff',\n });\n btn.onTriggered = () => this._sendQuickReply(message);\n });\n });\n\n grid.addRow({ weight: 0.06 }).addText({\n text: 'Talk via Text',\n fontColor: '#9b9bff',\n fontSize: 0.055,\n });\n\n this.typedTextView = grid.addRow({ weight: 0.18 }).addText({\n text: 'Tap to type...',\n fontColor: '#ffffff',\n fontSize: 0.065,\n textAlign: 'left',\n });\n\n const actionRow = grid.addRow({ weight: 0.30 });\n\n const kbBtn = actionRow.addCol({ weight: 0.5 }).addIconButton({\n text: 'keyboard',\n fontSize: 0.5,\n backgroundColor: '#2e3a4a',\n });\n kbBtn.onTriggered = () => this._toggleKeyboard();\n\n const sendBtn = actionRow.addCol({ weight: 0.5 }).addIconButton({\n text: 'send',\n fontSize: 0.5,\n backgroundColor: '#1a4a2a',\n });\n sendBtn.onTriggered = () => this._sendTypedText();\n\n this.replyPanel.updateLayouts();\n}\n```\n\nJust like with the Call panel, we will have a function to remove the Reply panel:\n`// ⌄⌄⌄ Remove Reply panel ⌄⌄⌄`\n\n```js\n_removeReplyPanel() {\n this._hideKeyboard();\n if (this.replyPanel) {\n this.remove(this.replyPanel);\n this.replyPanel = null;\n this.typedTextView = null;\n }\n this._currentTypedText = '';\n}\n```\n\nThis function answers the call and updates the status and call control section:\n`// ⌄⌄⌄ Answer call method ⌄⌄⌄`\n\n```js\n_onAnswer() {\n console.log('Answering...');\n this.client.answer(this.callId)\n .then(() => {\n console.log(\"Success answering call.\");\n this.statusText.text = `Call answered.`;\n this.updateControlRow('CONNECTED');\n\n // ⌄⌄⌄ Show reply panel alongside the call panel ⌄⌄⌄\n this._createReplyPanel();\n\n // get media stream\n const audioElement = this.client.getAudioOutputElement();\n if (audioElement && audioElement.srcObject) {\n // This is the active WebRTC MediaStream managed by Vonage\n const remoteStream = audioElement.srcObject;\n console.log('remoteStream: ', remoteStream);\n\n // Example: Grab individual audio tracks from the stream\n const audioTracks = remoteStream.getAudioTracks();\n console.log(\"Active Audio Tracks:\", audioTracks);\n\n // ⌄⌄⌄ Spin up the lipsync avatar driven by the remote stream ⌄⌄⌄\n this._createAvatar(remoteStream);\n }\n })\n .catch(error => {\n console.error(\"Error answering call: \", error);\n });\n}\n```\n\nThis function will reject the incoming call and remove the panel:\n`// ⌄⌄⌄ Reject call method ⌄⌄⌄`\n\n```js\n_onReject() {\n console.log('Rejecting...');\n this.client.reject(this.callId)\n .then(() => {\n console.log(\"Success rejecting call.\");\n })\n .catch(error => {\n console.error(\"Error rejecting call: \", error);\n });\n this._removeCallPanel();\n this._removeAvatar();\n}\n```\n\nThis function will hang up the ongoing call and remove the panel:\n`// ⌄⌄⌄ Hang Up call method ⌄⌄⌄ `\n\n```js\n_onHangup() {\n console.log('Hanging up...');\n this.client.hangup(this.callId)\n .then(() => {\n console.log(\"Success hanging up call.\");\n })\n .catch(error => {\n console.error(\"Error hanging up call: \", error);\n });\n // We manually destroy the panel here too, just in case the event lags\n this._removeCallPanel();\n this._removeAvatar();\n}\n```\n\nSet up some listeners for the events that the Vonage Client SDK will emit and what to do:\n`// ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄`\n\n```js\nsetupVonageListeners() {\n // --- CREATE UI ON INVITE ---\n this.client.on('callInvite', (callId, from, channelType) => {\n this.callId = callId;\n const maskedNumber = from.replace(/\\d(?=(?:\\D*\\d){4})/g, \"*\")\n console.log(`Incoming call from ${maskedNumber}`);\n\n // Trigger the UI creation here\n this._createCallPanel(maskedNumber);\n });\n\n this.client.on('legStatusUpdate', (callId, legId, status) => {\n console.log(\"status: \", status);\n if (this.statusText) {\n this.statusText.text = `Status: ${status}`;\n }\n });\n\n // --- REMOVE UI ON CANCEL/HANGUP ---\n this.client.on('callInviteCancel', (callId) => {\n console.log(`Call cancelled: ${callId}`);\n this.callId = null;\n this._removeCallPanel();\n this._removeAvatar();\n });\n\n this.client.on(\"callHangup\", (callId, callQuality, reason) => {\n console.log(`Call hung up: ${reason}`);\n this.callId = null;\n this._removeCallPanel();\n this._removeAvatar();\n });\n}\n```\n\nGet a token from the server so you can connect to a session:\n`// ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ `\n\n```js\nasync connectToVonage(name) {\n try {\n console.log(`Fetching token for ${name}...`);\n\n // 1. Fetch the token (AWAIT the result)\n const response = await fetch(`/token?name=${name}`);\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data = await response.json();\n this.token = data.token;\n console.log(\"Fetched token successfully.\");\n\n // 2. Create the Session (AWAIT the result)\n const sessionId = await this.client.createSession(this.token);\n\n console.log(\"Session created successfully. Session ID:\", sessionId);\n\n // 3. Update UI\n // Instead, update your XR Panel text to show we are ready\n if(this.statusText) {\n this.statusText.text = \"Connected. Waiting for calls...\";\n }\n\n } catch (error) {\n console.error(\"Connection failed:\", error);\n if(this.statusText) this.statusText.text = \"Connection Failed.\";\n }\n}\n```\n\nInitialize the Class when loaded into the page:\n`// ⌄⌄⌄ Initialize ⌄⌄⌄`\n\n```js\ninit() {\n console.log(\"Vonage init!\",this.client);\n this.setupVonageListeners();\n this.connectToVonage(this.userName);\n}\n```","src/content/docs/04_Vonage_Call_Panel.md","35a9af8a8ca7718e",{"html":101,"metadata":102},"\u003Cp>Now, we’ll be creating the UI.\u003C/p>\n\u003Cp>To recieve phone calls via the Vonage Voice API using the XR Blocks library’s \u003Ca href=\"https://xrblocks.github.io/docs/api/classes/SpatialPanel/\" target=\"_blank\">SpatialPanel Class\u003C/a>.\u003C/p>\n\u003Cp>To show the 3D Avatar for the caller, we will use the \u003Ca href=\"https://xrblocks.github.io/docs/manual/Lipsync/\" target=\"_blank\">Lipsync (Addon)\u003C/a>.\u003C/p>\n\u003Cp>The Vonage Voice Client SDK’s \u003Ca href=\"https://developer.vonage.com/en/vonage-client-sdk/in-app-voice/guides/say-call\" target=\"_blank\">Text to Speech\u003C/a> will be used to send the quick replies and typed messages into the call.\u003C/p>\n\u003Cp>The virtual keyboard that allows us to type those messages will come from the \u003Ca href=\"https://xrblocks.github.io/docs/manual/UI/#virtual-keyboard-addon\" target=\"_blank\">Virtual Keyboard (Addon)\u003C/a>.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">VonageAudioCall.js\u003C/code> file.\u003C/p>\n\u003Cp>First, we will set the Quick Replies that the user can send into the call.\nFind \u003Ccode dir=\"auto\">// ⌄⌄⌄ Set Quick Replies ⌄⌄⌄\u003C/code> and add this code:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">QUICK_REPLIES\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> =\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ label: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Meeting\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, message: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">In a meeting, I'll call you back.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ label: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Talk Later\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, message: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Can't talk right now. I'll talk later.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ label: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">OMW!\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, message: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">On my way! Talk soon.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ label: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">5 Mins\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, message: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Call you back in 5 minutes.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">];\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const QUICK_REPLIES = [ { label: "Meeting", message: "In a meeting, I'll call you back." }, { label: "Talk Later", message: "Can't talk right now. I'll talk later." }, { label: "OMW!", message: "On my way! Talk soon." }, { label: "5 Mins", message: "Call you back in 5 minutes." },];\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Let’s initiate the constructor for our panel with some variables:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create constructor ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">constructor\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">super\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">vonageClientSDK\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">VonageClient\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Keep a reference to the panel so we can destroy it later\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">userName\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">XR_User_1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">puppetHead\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mouth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">_camWorld\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">THREE\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Vector3\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">_headWorld\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">THREE\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Vector3\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">typedTextView\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">_currentTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"constructor() { super(); this.token = ''; this.client = new vonageClientSDK.VonageClient(); this.callId = null; // Keep a reference to the panel so we can destroy it later this.panel = null; this.statusText = null; this.userName = "XR_User_1"; this.grid = null; this.controlRow = null; this.puppetHead = null; this.face = null; this.mouth = null; this._camWorld = new THREE.Vector3(); this._headWorld = new THREE.Vector3(); this.replyPanel = null; this.typedTextView = null; this._currentTypedText = ''; this.keyboard = null;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Here’s the function to create an Avatar and add the MediaStream for the LipSync feature: \u003Ccode dir=\"auto\">// ⌄⌄⌄ Create 3D Avatar ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_createAvatar\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">stream\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Safety: don't create a second avatar if one already exists\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">puppetHead\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Creating lipsync avatar...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">faceR\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">head\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">THREE\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Position: in front of the user, roughly at face height\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">head\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- Sphere face mesh ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">faceGeom\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">THREE\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">SphereGeometry\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">faceR\u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">32\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">24\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">faceMat\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">THREE\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">MeshStandardMaterial\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">color: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0xf2d4b3\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">roughness: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.6\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">metalness: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.05\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">faceMesh\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">THREE\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Mesh\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">faceGeom\u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">faceMat\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">head\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">faceMesh\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">StylizedFace\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ showEyes: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">head\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mouth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">LipsyncMouth\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">stream\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, { target: \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">head\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mouth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">puppetHead\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">head\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">;\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">head\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_createAvatar(stream) { // Safety: don't create a second avatar if one already exists if (this.puppetHead) return; console.log("Creating lipsync avatar..."); const faceR = 0.1; const head = new THREE.Group(); // Position: in front of the user, roughly at face height head.position.set(0, xb.user.height, -1.2); // --- Sphere face mesh --- const faceGeom = new THREE.SphereGeometry(faceR, 32, 24); const faceMat = new THREE.MeshStandardMaterial({ color: 0xf2d4b3, roughness: 0.6, metalness: 0.05, }); const faceMesh = new THREE.Mesh(faceGeom, faceMat); head.add(faceMesh); this.face = new xb.StylizedFace({ showEyes: true }); head.add(this.face); this.mouth = new LipsyncMouth(stream, { target: this.face }); head.add(this.mouth); this.puppetHead = head; this.add(head);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will remove the 3D Avatar when the call is over:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Remove 3D Avatar ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeAvatar\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">puppetHead\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Removing lipsync avatar...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mouth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Detach from the head group before nulling the reference\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">mouth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">parent\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mouth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mouth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">face\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">parent\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// dispose() frees the underlying canvas/texture to avoid memory leaks\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">face\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">dispose\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">face\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">puppetHead\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">puppetHead\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_removeAvatar() { if (!this.puppetHead) return; console.log("Removing lipsync avatar..."); if (this.mouth) { // Detach from the head group before nulling the reference this.mouth.parent?.remove(this.mouth); this.mouth = null; } if (this.face) { this.face.parent?.remove(this.face); // dispose() frees the underlying canvas/texture to avoid memory leaks this.face.dispose(); this.face = null; } this.remove(this.puppetHead); this.puppetHead = null;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Here’s the function to create the panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create Call panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_createCallPanel\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">callerName\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// SAFETY: If a panel already exists, don't create another one.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Creating Call UI...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Create the Panel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">SpatialPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#2b2b2baa\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">objectDistance\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addGrid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Status Text\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.7\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Incoming call from \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">callerName\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ffffff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.08\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateControlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">INCOMING\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_createCallPanel(callerName) { // SAFETY: If a panel already exists, don't create another one. if (this.panel) return; console.log("Creating Call UI..."); // 1. Create the Panel this.panel = new xb.SpatialPanel({ backgroundColor: '#2b2b2baa' }); this.panel.position.set( 0, xb.user.height - 0.5, -xb.user.objectDistance ); this.add(this.panel); this.grid = this.panel.addGrid(); // 2. Status Text this.statusText = this.grid.addRow({ weight: 0.7 }).addText({ text: `Incoming call from ${callerName}...`, fontColor: '#ffffff', fontSize: 0.08, }); this.updateControlRow('INCOMING');}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Function to update the call control section:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Update Call controls ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateControlRow\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">state\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Remove the existing row if it exists\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">resetLayout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Create a fresh row. It will naturally append below the Status Text.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// We give it the full remaining weight (0.3 relative to the panel, or flexible)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.3\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">state\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">INCOMING\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- ANSWER BUTTON ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">answerBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">controlRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">call\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#00ff00\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">answerBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onAnswer\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- REJECT BUTTON ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">rejectBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">controlRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">call_end\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ff0000\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">rejectBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onReject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">else\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">state\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">CONNECTED\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- HANGUP BUTTON ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// This is a fresh row, so layouts will calculate correctly\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hangupBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">controlRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">call_end\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ff0000\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">hangupBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onHangup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 3. Force layout update\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateLayouts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"updateControlRow(state) { if (!this.grid) return; // 1. Remove the existing row if it exists if (this.controlRow) { this.grid.remove(this.controlRow); this.controlRow = null; this.grid.resetLayout(); } // 2. Create a fresh row. It will naturally append below the Status Text. // We give it the full remaining weight (0.3 relative to the panel, or flexible) this.controlRow = this.grid.addRow({ weight: 0.3 }); if (state === 'INCOMING') { // --- ANSWER BUTTON --- const answerBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({ text: 'call', fontSize: 0.5, backgroundColor: '#00ff00' }); answerBtn.onTriggered = () => this._onAnswer(); // --- REJECT BUTTON --- const rejectBtn = this.controlRow.addCol({ weight: 0.5 }).addIconButton({ text: 'call_end', fontSize: 0.5, backgroundColor: '#ff0000' }); rejectBtn.onTriggered = () => this._onReject(); } else if (state === 'CONNECTED') { // --- HANGUP BUTTON --- // This is a fresh row, so layouts will calculate correctly const hangupBtn = this.controlRow.addCol({ weight: 1 }).addIconButton({ text: 'call_end', fontSize: 0.5, backgroundColor: '#ff0000' }); hangupBtn.onTriggered = () => this._onHangup(); } // 3. Force layout update this.panel.updateLayouts();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will remove the panel once the call is over:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Remove Call panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Destroying Call UI...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">controlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeReplyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_removeCallPanel() { if (this.panel) { console.log("Destroying Call UI..."); this.remove(this.panel); this.panel = null; this.grid = null; this.statusText = null; this.controlRow = null; } this._removeReplyPanel();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Now, let’s add the Virtual Keyboard that will allow us to send text messages that will be spoken into the call.\u003C/p>\n\u003Cp>Here’s the code to show the Keyboard:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Show Virtual Keyboard ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_showKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Position it below and aligned with the reply panel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">keyboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.35\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">objectDistance\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">+\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Update the display on every keystroke\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">keyboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTextChanged\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">text\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">_currentTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">;\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">typedTextView\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">typedTextView\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">length\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Tap to type...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Enter key sends immediately — same as tapping the Send button\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">keyboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onEnterPressed\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">text\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_sendTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_showKeyboard() { if (this.keyboard) return; this.keyboard = new Keyboard(); // Position it below and aligned with the reply panel this.keyboard.position.set( 0, xb.user.height - 1.35, -xb.user.objectDistance + 1 ); this.add(this.keyboard); // Update the display on every keystroke this.keyboard.onTextChanged = (text) => { this._currentTypedText = text; if (this.typedTextView) { this.typedTextView.text = text.length > 0 ? text : 'Tap to type...'; } }; // Enter key sends immediately — same as tapping the Send button this.keyboard.onEnterPressed = (text) => { this._sendTypedText(); };}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>If we want to hide the Keyboard, here’s the code:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Hide Virtual Keyboard ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_hideKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_hideKeyboard() { if (!this.keyboard) return; this.remove(this.keyboard); this.keyboard = null;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>To toggle between showing and hidding the keyboard, we have this code:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Toggle Virtual Keyboard ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_toggleKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_hideKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_showKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_toggleKeyboard() { this.keyboard ? this._hideKeyboard() : this._showKeyboard();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Let’s create the functions that will send the text to be said into the call just in case we can’t talk at that moment.\u003C/p>\n\u003Cp>To send the Quick Replies that we set before:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Send Quick Reply ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_sendQuickReply\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">message\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Sending quick reply: \"\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">message\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Give the user immediate visual feedback in the status bar\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Sending...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">say\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">message\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">)\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Quick reply sent successfully.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Sent: \"\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">message\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">err\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">say() error:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">err\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Failed to send message.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_sendQuickReply(message) { if (!this.callId) return; console.log(`Sending quick reply: "${message}"`); // Give the user immediate visual feedback in the status bar if (this.statusText) this.statusText.text = 'Sending...'; this.client.say(this.callId, message) .then(() => { console.log('Quick reply sent successfully.'); if (this.statusText) this.statusText.text = `Sent: "${message}"`; }) .catch(err => { console.error('say() error:', err); if (this.statusText) this.statusText.text = 'Failed to send message.'; });}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>In the case we want to carry on the conversation but maybe can’t speak (ie in a public space), we can send custom text:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Send Custom Text ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_sendTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">text\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">_currentTypedText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">trim\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Sending typed text: \"\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">text\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Sending...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">say\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">)\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Typed text sent successfully.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Sent: \"\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">text\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Clear the keyboard buffer and reset the display\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">keyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">keyboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">_currentTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">typedTextView\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">typedTextView\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Tap to type...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">err\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">say() error:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">err\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Failed to send message.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_sendTypedText() { const text = this._currentTypedText.trim(); if (!text) return; if (!this.callId) return; console.log(`Sending typed text: "${text}"`); if (this.statusText) this.statusText.text = 'Sending...'; this.client.say(this.callId, text) .then(() => { console.log('Typed text sent successfully.'); if (this.statusText) this.statusText.text = `Sent: "${text}"`; // Clear the keyboard buffer and reset the display if (this.keyboard) this.keyboard.setText(''); this._currentTypedText = ''; if (this.typedTextView) this.typedTextView.text = 'Tap to type...'; }) .catch(err => { console.error('say() error:', err); if (this.statusText) this.statusText.text = 'Failed to send message.'; });}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Here we will create the Reply panel that will hold all the way we can send a text message into the call:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create Reply panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_createReplyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">SpatialPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#1a1a2ecc\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">width: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">.75\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">height: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.9\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Offset to the right so it sits beside the main call panel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">replyPanel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.8\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">objectDistance\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">replyPanel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addGrid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.06\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Quick Replies\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#9b9bff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.055\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pairs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> =\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">QUICK_REPLIES\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">slice\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">), \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// [ Meeting, Talk Later ]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">QUICK_REPLIES\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">slice\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">4\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">), \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// [ OMW!, 5 Mins ]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">pairs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">forEach\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">pair\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">row\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.20\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">pair\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">forEach\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">{ \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">label\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">message\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> }\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">btn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">row\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addTextButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">label\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.35\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#2e2e50\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ffffff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">btn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_sendQuickReply\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">message\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.06\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Talk via Text\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#9b9bff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.055\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">typedTextView\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.18\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Tap to type...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ffffff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.065\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">textAlign: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">left\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">actionRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.30\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">kbBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">actionRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">keyboard\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#2e3a4a\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">kbBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_toggleKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sendBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">actionRow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addCol\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addIconButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">send\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#1a4a2a\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">sendBtn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTriggered\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_sendTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">replyPanel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateLayouts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_createReplyPanel() { if (this.replyPanel) return; this.replyPanel = new xb.SpatialPanel({ backgroundColor: '#1a1a2ecc', width: .75, height: 0.9, }); // Offset to the right so it sits beside the main call panel this.replyPanel.position.set( 0.8, xb.user.height - 0.5, -xb.user.objectDistance ); this.add(this.replyPanel); const grid = this.replyPanel.addGrid(); grid.addRow({ weight: 0.06 }).addText({ text: 'Quick Replies', fontColor: '#9b9bff', fontSize: 0.055, }); const pairs = [ QUICK_REPLIES.slice(0, 2), // [ Meeting, Talk Later ] QUICK_REPLIES.slice(2, 4), // [ OMW!, 5 Mins ] ]; pairs.forEach(pair => { const row = grid.addRow({ weight: 0.20 }); pair.forEach(({ label, message }) => { const btn = row.addCol({ weight: 0.5 }).addTextButton({ text: label, fontSize: 0.35, backgroundColor: '#2e2e50', fontColor: '#ffffff', }); btn.onTriggered = () => this._sendQuickReply(message); }); }); grid.addRow({ weight: 0.06 }).addText({ text: 'Talk via Text', fontColor: '#9b9bff', fontSize: 0.055, }); this.typedTextView = grid.addRow({ weight: 0.18 }).addText({ text: 'Tap to type...', fontColor: '#ffffff', fontSize: 0.065, textAlign: 'left', }); const actionRow = grid.addRow({ weight: 0.30 }); const kbBtn = actionRow.addCol({ weight: 0.5 }).addIconButton({ text: 'keyboard', fontSize: 0.5, backgroundColor: '#2e3a4a', }); kbBtn.onTriggered = () => this._toggleKeyboard(); const sendBtn = actionRow.addCol({ weight: 0.5 }).addIconButton({ text: 'send', fontSize: 0.5, backgroundColor: '#1a4a2a', }); sendBtn.onTriggered = () => this._sendTypedText(); this.replyPanel.updateLayouts();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Just like with the Call panel, we will have a function to remove the Reply panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Remove Reply panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeReplyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_hideKeyboard\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remove\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">replyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">typedTextView\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">_currentTypedText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_removeReplyPanel() { this._hideKeyboard(); if (this.replyPanel) { this.remove(this.replyPanel); this.replyPanel = null; this.typedTextView = null; } this._currentTypedText = '';}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function answers the call and updates the status and call control section:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Answer call method ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onAnswer\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Answering...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">answer\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Success answering call.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Call answered.\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateControlRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">CONNECTED\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ⌄⌄⌄ Show reply panel alongside the call panel ⌄⌄⌄\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_createReplyPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// get media stream\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">audioElement\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getAudioOutputElement\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">audioElement\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">audioElement\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">srcObject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// This is the active WebRTC MediaStream managed by Vonage\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">remoteStream\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">audioElement\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">srcObject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">remoteStream: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">remoteStream\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Example: Grab individual audio tracks from the stream\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">audioTracks\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">remoteStream\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getAudioTracks\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Active Audio Tracks:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">audioTracks\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ⌄⌄⌄ Spin up the lipsync avatar driven by the remote stream ⌄⌄⌄\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_createAvatar\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">remoteStream\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Error answering call: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_onAnswer() { console.log('Answering...'); this.client.answer(this.callId) .then(() => { console.log("Success answering call."); this.statusText.text = `Call answered.`; this.updateControlRow('CONNECTED'); // ⌄⌄⌄ Show reply panel alongside the call panel ⌄⌄⌄ this._createReplyPanel(); // get media stream const audioElement = this.client.getAudioOutputElement(); if (audioElement && audioElement.srcObject) { // This is the active WebRTC MediaStream managed by Vonage const remoteStream = audioElement.srcObject; console.log('remoteStream: ', remoteStream); // Example: Grab individual audio tracks from the stream const audioTracks = remoteStream.getAudioTracks(); console.log("Active Audio Tracks:", audioTracks); // ⌄⌄⌄ Spin up the lipsync avatar driven by the remote stream ⌄⌄⌄ this._createAvatar(remoteStream); } }) .catch(error => { console.error("Error answering call: ", error); });}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will reject the incoming call and remove the panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Reject call method ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onReject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Rejecting...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">reject\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Success rejecting call.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Error rejecting call: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeAvatar\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_onReject() { console.log('Rejecting...'); this.client.reject(this.callId) .then(() => { console.log("Success rejecting call."); }) .catch(error => { console.error("Error rejecting call: ", error); }); this._removeCallPanel(); this._removeAvatar();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This function will hang up the ongoing call and remove the panel:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Hang Up call method ⌄⌄⌄ \u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_onHangup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Hanging up...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hangup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">then\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Success hanging up call.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">})\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Error hanging up call: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// We manually destroy the panel here too, just in case the event lags\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeAvatar\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"_onHangup() { console.log('Hanging up...'); this.client.hangup(this.callId) .then(() => { console.log("Success hanging up call."); }) .catch(error => { console.error("Error hanging up call: ", error); }); // We manually destroy the panel here too, just in case the event lags this._removeCallPanel(); this._removeAvatar();}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Set up some listeners for the events that the Vonage Client SDK will emit and what to do:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setupVonageListeners\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- CREATE UI ON INVITE ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">callInvite\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">channelType\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">;\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">maskedNumber\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">from\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">replace\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">/\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">\\d\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">(?=(?:\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">\\D\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">\\d\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">{4}\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">)\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">/\u003C/span>\u003Cspan style=\"--0:#5CA7E4;--1:#3A688F\">g\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">*\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Incoming call from \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">maskedNumber\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Trigger the UI creation here\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_createCallPanel\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">maskedNumber\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">legStatusUpdate\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">legId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">status\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">status: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">status\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Status: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">status\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// --- REMOVE UI ON CANCEL/HANGUP ---\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">callInviteCancel\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">callId\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Call cancelled: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">callId\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeAvatar\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">on\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">callHangup\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">callQuality\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">reason\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Call hung up: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">reason\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">callId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeCallPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">_removeAvatar\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"setupVonageListeners() { // --- CREATE UI ON INVITE --- this.client.on('callInvite', (callId, from, channelType) => { this.callId = callId; const maskedNumber = from.replace(/\\d(?=(?:\\D*\\d){4})/g, "*") console.log(`Incoming call from ${maskedNumber}`); // Trigger the UI creation here this._createCallPanel(maskedNumber); }); this.client.on('legStatusUpdate', (callId, legId, status) => { console.log("status: ", status); if (this.statusText) { this.statusText.text = `Status: ${status}`; } }); // --- REMOVE UI ON CANCEL/HANGUP --- this.client.on('callInviteCancel', (callId) => { console.log(`Call cancelled: ${callId}`); this.callId = null; this._removeCallPanel(); this._removeAvatar(); }); this.client.on("callHangup", (callId, callQuality, reason) => { console.log(`Call hung up: ${reason}`); this.callId = null; this._removeCallPanel(); this._removeAvatar(); });}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Get a token from the server so you can connect to a session:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ \u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">async\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">connectToVonage\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">name\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">try\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Fetching token for \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">name\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Fetch the token (AWAIT the result)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fetch\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">/token?name=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">name\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">ok\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">throw\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">HTTP error! status: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">status\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">json\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Fetched token successfully.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Create the Session (AWAIT the result)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sessionId\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">client\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createSession\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">token\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Session created successfully. Session ID:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">sessionId\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 3. Update UI\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Instead, update your XR Panel text to show we are ready\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Connected. Waiting for calls...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">catch\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> (\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Connection failed:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">error\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">statusText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Connection Failed.\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"async connectToVonage(name) { try { console.log(`Fetching token for ${name}...`); // 1. Fetch the token (AWAIT the result) const response = await fetch(`/token?name=${name}`); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); this.token = data.token; console.log("Fetched token successfully."); // 2. Create the Session (AWAIT the result) const sessionId = await this.client.createSession(this.token); console.log("Session created successfully. Session ID:", sessionId); // 3. Update UI // Instead, update your XR Panel text to show we are ready if(this.statusText) { this.statusText.text = "Connected. Waiting for calls..."; } } catch (error) { console.error("Connection failed:", error); if(this.statusText) this.statusText.text = "Connection Failed."; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Initialize the Class when loaded into the page:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Initialize ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">init\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Vonage init!\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setupVonageListeners\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">connectToVonage\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">userName\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"init() { console.log("Vonage init!",this.client); this.setupVonageListeners(); this.connectToVonage(this.userName);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":103,"localImagePaths":104,"remoteImagePaths":105,"frontmatter":106,"imagePaths":107},[],[],[],{"title":92,"description":93},[],"05_exit_button",{"id":108,"data":110,"body":116,"filePath":117,"digest":118,"rendered":119},{"title":111,"description":112,"editUrl":16,"head":113,"template":33,"sidebar":114,"pagefind":16,"draft":23},"Exiting WebXR application","Button to exit WebXR application",[],{"hidden":23,"attrs":115},{},"When in the WebXR environment using a headset, I could not figure out how to leave the experience, so I made an Exit Demo Panel.\n\nThe following code will be placed in the `ExitButton.js` file.\n\nCreate the constructor for the Class:\n`// ⌄⌄⌄ Create constructor ⌄⌄⌄`\n```js\n constructor() {\n super();\n // Keep a reference to the panel so we can destroy it later\n this.panel = null; \n this.statusText = null;\n this.exitPanelText = \"Exit Demo\";\n }\n```\n\nFunction to create a panel for the Exit Button:\n`// ⌄⌄⌄ Create Exit Button panel ⌄⌄⌄`\n```js\n createExitPanel() {\n // SAFETY: If a panel already exists, don't create another one.\n if (this.panel) return;\n\n console.log(\"Creating Exit Button...\");\n \n // 1. Create the Panel\n this.panel = new xb.SpatialPanel({\n width: 0.5,\n height: 0.5, \n backgroundColor: '#2b2b2baa'\n });\n\n this.panel.position.set(\n 0,\n xb.user.height,\n 2.0\n );\n\n this.panel.rotation.set(0, Math.PI, 0);\n this.add(this.panel);\n\n const grid = this.panel.addGrid();\n\n // 2. Status Text\n this.statusText = grid.addRow({ weight: 1 }).addText({\n text: this.exitPanelText,\n fontColor: '#ffffff',\n fontSize: .4,\n });\n\n // Orbiter\n const orbiter = grid.addOrbiter();\n orbiter.addExitButton();\n this.panel.updateLayouts();\n }\n```\n\nInitialize Class when loaded into the page:\n`// ⌄⌄⌄ Initialize ⌄⌄⌄`\n```js\n init() {\n console.log(\"Exit Button init!\",this.client);\n this.createExitPanel();\n }\n```","src/content/docs/05_Exit_Button.md","8a1b55e67864fa9e",{"html":120,"metadata":121},"\u003Cp>When in the WebXR environment using a headset, I could not figure out how to leave the experience, so I made an Exit Demo Panel.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">ExitButton.js\u003C/code> file.\u003C/p>\n\u003Cp>Create the constructor for the Class:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create constructor ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">constructor\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">super\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Keep a reference to the panel so we can destroy it later\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">exitPanelText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Exit Demo\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" constructor() { super(); // Keep a reference to the panel so we can destroy it later this.panel = null; this.statusText = null; this.exitPanelText = "Exit Demo"; }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Function to create a panel for the Exit Button:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Create Exit Button panel ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createExitPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// SAFETY: If a panel already exists, don't create another one.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Creating Exit Button...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Create the Panel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">SpatialPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">width: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">height: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">backgroundColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#2b2b2baa\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">height\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2.0\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">rotation\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">Math\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">PI\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addGrid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Status Text\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statusText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({ weight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> })\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text: \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">exitPanelText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontColor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ffffff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">.4\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Orbiter\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">orbiter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">grid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addOrbiter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">orbiter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addExitButton\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">panel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateLayouts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" createExitPanel() { // SAFETY: If a panel already exists, don't create another one. if (this.panel) return; console.log("Creating Exit Button..."); // 1. Create the Panel this.panel = new xb.SpatialPanel({ width: 0.5, height: 0.5, backgroundColor: '#2b2b2baa' }); this.panel.position.set( 0, xb.user.height, 2.0 ); this.panel.rotation.set(0, Math.PI, 0); this.add(this.panel); const grid = this.panel.addGrid(); // 2. Status Text this.statusText = grid.addRow({ weight: 1 }).addText({ text: this.exitPanelText, fontColor: '#ffffff', fontSize: .4, }); // Orbiter const orbiter = grid.addOrbiter(); orbiter.addExitButton(); this.panel.updateLayouts(); }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Initialize Class when loaded into the page:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ Initialize ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">init\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">() {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Exit Button init!\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">client\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">this\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createExitPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" init() { console.log("Exit Button init!",this.client); this.createExitPanel(); }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>",{"headings":122,"localImagePaths":123,"remoteImagePaths":124,"frontmatter":125,"imagePaths":126},[],[],[],{"title":111,"description":112},[],"06_add_to_xr_blocks",{"id":127,"data":129,"body":135,"filePath":136,"digest":137,"rendered":138},{"title":130,"description":131,"editUrl":16,"head":132,"template":33,"sidebar":133,"pagefind":16,"draft":23},"Add panels to XR Blocks","adding panels to WebXR application",[],{"hidden":23,"attrs":134},{},"Let's add the 2 panels to the application.\n\nThe following code will be placed in the `main.js` file.\n\nFirst, import the Panels:\n`// ⌄⌄⌄ import Vonage Call Panel and Exit Button ⌄⌄⌄`\n```js\nimport { VonageAudioCall } from './VonageAudioCall.js';\nimport { ExitPanel } from './ExitButton.js';\n```\n\nCreate instances and add to the application:\n`// ⌄⌄⌄ add Vonage Call Panel and Exit Button ⌄⌄⌄`\n```js\nxb.add(new VonageAudioCall());\nxb.add(new ExitPanel());\n```\n\n## Time to test the application\nRefresh the application and try to call the phone number that was purchased and assigned while running the setup script.\n\n> Note: You can find the phone number connected to your Vonage application in the `.env` file.","src/content/docs/06_Add_To_XR_Blocks.md","d3b20f81f928d1fb",{"html":139,"metadata":140},"\u003Cp>Let’s add the 2 panels to the application.\u003C/p>\n\u003Cp>The following code will be placed in the \u003Ccode dir=\"auto\">main.js\u003C/code> file.\u003C/p>\n\u003Cp>First, import the Panels:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ import Vonage Call Panel and Exit Button ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { VonageAudioCall } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./VonageAudioCall.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { ExitPanel } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./ExitButton.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { VonageAudioCall } from './VonageAudioCall.js';import { ExitPanel } from './ExitButton.js';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Create instances and add to the application:\n\u003Ccode dir=\"auto\">// ⌄⌄⌄ add Vonage Call Panel and Exit Button ⌄⌄⌄\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"js\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">VonageAudioCall\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">());\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">xb\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">ExitPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">());\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"xb.add(new VonageAudioCall());xb.add(new ExitPanel());\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"time-to-test-the-application\">Time to test the application\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#time-to-test-the-application\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “Time to test the application”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Refresh the application and try to call the phone number that was purchased and assigned while running the setup script.\u003C/p>\n\u003Cblockquote>\n\u003Cp>Note: You can find the phone number connected to your Vonage application in the \u003Ccode dir=\"auto\">.env\u003C/code> file.\u003C/p>\n\u003C/blockquote>",{"headings":141,"localImagePaths":145,"remoteImagePaths":146,"frontmatter":147,"imagePaths":148},[142],{"depth":82,"slug":143,"text":144},"time-to-test-the-application","Time to test the application",[],[],{"title":130,"description":131},[],"07_congrats",{"id":149,"data":151,"body":157,"filePath":158,"digest":159,"rendered":160},{"title":152,"description":153,"editUrl":16,"head":154,"template":33,"sidebar":155,"pagefind":16,"draft":23},"Congratulations!","What's next.",[],{"hidden":23,"attrs":156},{},"## You did it!\n\nYou now have a WebXR application using XR Blocks and the Vonage Voice API that can receive phone calls.\n\n## Export your application\n\nIf you'd like to save the application you created to your personal GitHub acoount, open a new Terminal window (press the + button) and run this command:\n\n```bash\nchmod +x export.sh && ./export.sh\n```\n\n## Create your own XR Blocks application with AI\n\nXR Blocks has a Google Gemini Gem, that allows you to create a WebXR application using just plain text. Want to create something? \u003Ca href=\"https://xrblocks.github.io/gem\" target=\"_blank\">Give it a try.\u003C/a>\n\n## What's Next?\n\n- Can you create a WebXR application that makes phone calls? How about a voice chat in a WebXR environment?\n- Learn more about the Vonage Voice API in our \u003Ca href=\"https://developer.vonage.com/en/voice/voice-api/overview\" target=\"_blank\">developer documenation\u003C/a>\n- Want to learn more about other Vonage products? Try our interactive \u003Ca href=\"https://developer.vonage.com/en/learning-center\" target=\"_blank\">Learning Center\u003C/a> and earn certificates.\n- Connect with us on \u003Ca href=\"https://x.com/vonagedev\" target=\"_blank\">Twitter / X\u003C/a>, \u003Ca href=\"https://bsky.app/profile/did:plc:btgbhfwrllglgvyuqrmi2sev\" target=\"_blank\">Bluesky\u003C/a> and \u003Ca href=\"https://www.linkedin.com/company/vonage-dev\" target=\"_blank\">LinkedIn\u003C/a>\n- Join our \u003Ca href=\"https://vonage.dev/slack\" target=\"_blank\">Developer Community Slack channel\u003C/a> to connect with others building with Vonage","src/content/docs/07_Congrats.md","53a92988967e5d1c",{"html":161,"metadata":162},"\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"you-did-it\">You did it!\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#you-did-it\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “You did it!”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>You now have a WebXR application using XR Blocks and the Vonage Voice API that can receive phone calls.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"export-your-application\">Export your application\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#export-your-application\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “Export your application”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>If you’d like to save the application you created to your personal GitHub acoount, open a new Terminal window (press the + button) and run this command:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chmod\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">+x\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">export.sh\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> && \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">./export.sh\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"chmod +x export.sh && ./export.sh\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"create-your-own-xr-blocks-application-with-ai\">Create your own XR Blocks application with AI\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#create-your-own-xr-blocks-application-with-ai\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “Create your own XR Blocks application with AI”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>XR Blocks has a Google Gemini Gem, that allows you to create a WebXR application using just plain text. Want to create something? \u003Ca href=\"https://xrblocks.github.io/gem\" target=\"_blank\">Give it a try.\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"whats-next\">What’s Next?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#whats-next\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\" data-pagefind-ignore=\"\">Section titled “What’s Next?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Can you create a WebXR application that makes phone calls? How about a voice chat in a WebXR environment?\u003C/li>\n\u003Cli>Learn more about the Vonage Voice API in our \u003Ca href=\"https://developer.vonage.com/en/voice/voice-api/overview\" target=\"_blank\">developer documenation\u003C/a>\u003C/li>\n\u003Cli>Want to learn more about other Vonage products? Try our interactive \u003Ca href=\"https://developer.vonage.com/en/learning-center\" target=\"_blank\">Learning Center\u003C/a> and earn certificates.\u003C/li>\n\u003Cli>Connect with us on \u003Ca href=\"https://x.com/vonagedev\" target=\"_blank\">Twitter / X\u003C/a>, \u003Ca href=\"https://bsky.app/profile/did:plc:btgbhfwrllglgvyuqrmi2sev\" target=\"_blank\">Bluesky\u003C/a> and \u003Ca href=\"https://www.linkedin.com/company/vonage-dev\" target=\"_blank\">LinkedIn\u003C/a>\u003C/li>\n\u003Cli>Join our \u003Ca href=\"https://vonage.dev/slack\" target=\"_blank\">Developer Community Slack channel\u003C/a> to connect with others building with Vonage\u003C/li>\n\u003C/ul>",{"headings":163,"localImagePaths":176,"remoteImagePaths":177,"frontmatter":178,"imagePaths":179},[164,167,170,173],{"depth":82,"slug":165,"text":166},"you-did-it","You did it!",{"depth":82,"slug":168,"text":169},"export-your-application","Export your application",{"depth":82,"slug":171,"text":172},"create-your-own-xr-blocks-application-with-ai","Create your own XR Blocks application with AI",{"depth":82,"slug":174,"text":175},"whats-next","What’s Next?",[],[],{"title":152,"description":153},[]] \ No newline at end of file diff --git a/tutorials/webxr-javascript-workshop/.astro/settings.json b/tutorials/webxr-javascript-workshop/.astro/settings.json index 3f75c6b8..c41bdd24 100644 --- a/tutorials/webxr-javascript-workshop/.astro/settings.json +++ b/tutorials/webxr-javascript-workshop/.astro/settings.json @@ -1,5 +1,5 @@ { "_variables": { - "lastUpdateCheck": 1775761538082 + "lastUpdateCheck": 1784923264156 } } \ No newline at end of file diff --git a/tutorials/webxr-javascript-workshop/README.md b/tutorials/webxr-javascript-workshop/README.md index c0e86086..57503460 100644 --- a/tutorials/webxr-javascript-workshop/README.md +++ b/tutorials/webxr-javascript-workshop/README.md @@ -8,6 +8,10 @@ Generated Tutorial Environment. ## 🛠️ Edit this Tutorial Want to make changes to the lesson, add steps, or update starter files? [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/Vonage-Community/tutorial-interactive_tutorials/tree/main/sources/webxr-javascript-workshop) +1. Clone this repo: `git clone https://github.com/Vonage-Community/tutorial-interactive_tutorials.git` +2. Open the `sources/webxr-javascript-workshop` folder in VS Code +3. Install dependencies and start the dev server: `npm install && npm run dev` +4. Preview at `http://localhost:4321` — open it in VS Code via **Ctrl+Shift+P** → **Simple Browser: Show** ### Environment Details - **Tutorial Steps**: Port 1234 diff --git a/tutorials/webxr-javascript-workshop/package-lock.json b/tutorials/webxr-javascript-workshop/package-lock.json index 17c9f0c4..c22aa404 100644 --- a/tutorials/webxr-javascript-workshop/package-lock.json +++ b/tutorials/webxr-javascript-workshop/package-lock.json @@ -3894,9 +3894,9 @@ "license": "MIT" }, "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", "dev": true, "license": "MIT", "dependencies": { @@ -4345,9 +4345,9 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "dev": true, "license": "MIT", "dependencies": { @@ -6774,13 +6774,14 @@ } }, "node_modules/qs": { - "version": "6.15.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", - "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -7340,15 +7341,15 @@ } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, diff --git a/tutorials/webxr-javascript-workshop/project/export.sh b/tutorials/webxr-javascript-workshop/project/export.sh new file mode 100644 index 00000000..3b2e60fa --- /dev/null +++ b/tutorials/webxr-javascript-workshop/project/export.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Ensure execution stops if a step fails +set -e + +echo "=========================================" +echo " 📦 Exporting Your Workshop Project " +echo "=========================================" + +# 1. Initialize a clean, local repository +echo "Initializing a brand new git tree..." +git init -b main + +# 2. Stage and commit all target workshop files +echo "Staging files..." +git add . +git commit -m "Initial commit: Completed Vonage Voice API Workshop" + +# 3. Use GitHub CLI for an elegant, interactive push +echo "" +echo "Let's upload this to your personal GitHub profile." +echo "Follow the prompts below to authenticate and name your new repository." +echo "--------------------------------------------------" + +# 'gh repo create' natively prompts the user if they want to create a repo from the current folder, +# names it, sets visibility, creates it on GitHub, and adds/pushes the remote automatically! +gh repo create --source=. --remote=origin --push + +echo "" +echo "=========================================" +echo " 🎉 SUCCESS! Your project is safely on GitHub." +echo "=========================================" + \ No newline at end of file diff --git a/tutorials/webxr-javascript-workshop/project/package-lock.json b/tutorials/webxr-javascript-workshop/project/package-lock.json index a9d3a5fd..909b0f8b 100644 --- a/tutorials/webxr-javascript-workshop/project/package-lock.json +++ b/tutorials/webxr-javascript-workshop/project/package-lock.json @@ -1267,9 +1267,9 @@ } }, "node_modules/path-to-regexp": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", - "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", "license": "MIT", "funding": { "type": "opencollective", @@ -1289,9 +1289,9 @@ } }, "node_modules/qs": { - "version": "6.15.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", - "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" diff --git a/tutorials/webxr-javascript-workshop/project/pages/app-to-app-inbound.html b/tutorials/webxr-javascript-workshop/project/pages/app-to-app-inbound.html new file mode 100644 index 00000000..8105e5ee --- /dev/null +++ b/tutorials/webxr-javascript-workshop/project/pages/app-to-app-inbound.html @@ -0,0 +1,94 @@ + + + + + App to App inbound + + + + + +

Inbound App Call ()

+

logging in...

+
+ + + + + + diff --git a/tutorials/webxr-javascript-workshop/project/pages/app-to-app-outbound.html b/tutorials/webxr-javascript-workshop/project/pages/app-to-app-outbound.html new file mode 100644 index 00000000..aee9182b --- /dev/null +++ b/tutorials/webxr-javascript-workshop/project/pages/app-to-app-outbound.html @@ -0,0 +1,130 @@ + + + + + App to App outbound + + + + + + < Home +

+

Outbound App Call

+
+

1. Enter name of user making the call:

+ + +

+ +
+
+

Logged in as:

+

2. Enter name of user receiving the call:

+ + +

+ *This will open a new tab and log in as this user. +
+ +
+
+ *Answer the call in the other tab. + + +
+ + + + diff --git a/tutorials/webxr-javascript-workshop/project/pages/app-to-phone.html b/tutorials/webxr-javascript-workshop/project/pages/app-to-phone.html new file mode 100644 index 00000000..eaef7193 --- /dev/null +++ b/tutorials/webxr-javascript-workshop/project/pages/app-to-phone.html @@ -0,0 +1,98 @@ + + + + + App to Phone + + + + + + < Home +

+

Call Phone from App

+ + + + +
+ + + + + diff --git a/tutorials/webxr-javascript-workshop/project/pages/index.html b/tutorials/webxr-javascript-workshop/project/pages/index.html index eac188b2..94e4ed8c 100644 --- a/tutorials/webxr-javascript-workshop/project/pages/index.html +++ b/tutorials/webxr-javascript-workshop/project/pages/index.html @@ -1,4 +1,4 @@ - + XR Blocks with Call Answering @@ -27,7 +27,8 @@ "lit": "https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js", "lit/": "https://esm.run/lit@3/", "xrblocks": "https://cdn.jsdelivr.net/gh/google/xrblocks@build/xrblocks.js", - "xrblocks/addons/": "https://cdn.jsdelivr.net/gh/google/xrblocks@build/addons/" + "xrblocks/addons/": "https://cdn.jsdelivr.net/gh/google/xrblocks@build/addons/", + "lipsync": "https://cdn.jsdelivr.net/gh/google/xrblocks@build/addons/lipsync/index.js" } } @@ -40,4 +41,4 @@ > - \ No newline at end of file + diff --git a/tutorials/webxr-javascript-workshop/project/pages/phone-to-app.html b/tutorials/webxr-javascript-workshop/project/pages/phone-to-app.html new file mode 100644 index 00000000..daba06bc --- /dev/null +++ b/tutorials/webxr-javascript-workshop/project/pages/phone-to-app.html @@ -0,0 +1,160 @@ + + + + + Phone to App + + + + + + < Home +

+
+

Login

+

To receive a call from a PSTN phone, you need to login first.

+ + +

+ +
+
+

Inbound PSTN phone call

+

Lines are open for calls...

+
+ + + +
+ + + + + diff --git a/tutorials/webxr-javascript-workshop/project/setup-project.js b/tutorials/webxr-javascript-workshop/project/setup-project.js index 2bae34e0..a42cea80 100644 --- a/tutorials/webxr-javascript-workshop/project/setup-project.js +++ b/tutorials/webxr-javascript-workshop/project/setup-project.js @@ -1,6 +1,7 @@ require('dotenv').config(); const fs = require('fs'); +const path = require('path'); const { Vonage } = require('@vonage/server-sdk'); @@ -12,24 +13,29 @@ console.log('setup.js running...'); if (process.env.VONAGE_API_KEY && process.env.VONAGE_API_SECRET) { // If the environment variables are already set, use them console.log('Environment variables already set. Skipping setup.'); - process.exit(); + process.exit(); } - + let step = 'SET_API_KEY'; console.log('Vonage setup utility for Github Codespaces -- press "q" to exit'); -console.log('This utility will need your Vonage API key and API secret. They will be saved to your .env file,'); -console.log('where they will be visible only to you and collaborators on this project.'); -console.log('Find your API key and secret at: https://dashboard.vonage.com/getting-started-guide'); +console.log( + 'This utility will need your Vonage API key and API secret. They will be saved to your .env file,' +); +console.log( + 'where they will be visible only to you and collaborators on this project.' +); +console.log( + 'Find your API key and secret at: https://dashboard.vonage.com/getting-started-guide' +); console.log('process.env.CODESPACE_NAME: ', process.env.CODESPACE_NAME); console.log('Enter your API Key:'); let input = process.stdin; -input.on('data', data => { - +input.on('data', (data) => { if (data.toString().trim() === 'q') { - // exit + // exit return process.exit(); } - + switch (step) { case 'SET_API_KEY': return setApiKey(data); @@ -51,12 +57,13 @@ input.on('data', data => { break; default: } - - }); function setApiKey(data) { - if (data.toString().replace(/\n/g, '').length === 0 || data.toString().replace(/\n/g, '') === ' ') { + if ( + data.toString().replace(/\n/g, '').length === 0 || + data.toString().replace(/\n/g, '') === ' ' + ) { console.log('(Can not be blank.) Enter you API key:'); } else { process.env.VONAGE_API_KEY = data.toString().replace(/\n/g, ''); @@ -67,7 +74,10 @@ function setApiKey(data) { } function setApiSecret(data) { - if (data.toString().replace(/\n/g, '').length === 0 || data.toString().replace(/\n/g, '') === ' ') { + if ( + data.toString().replace(/\n/g, '').length === 0 || + data.toString().replace(/\n/g, '') === ' ' + ) { console.log('(Can not be blank.) Enter you API secret:'); } else { process.env.VONAGE_API_SECRET = data.toString().replace(/\n/g, ''); @@ -78,73 +88,86 @@ function setApiSecret(data) { } function setAppName(data) { - if (data.toString().replace(/\n/g, '').length === 0 || data.toString().replace(/\n/g, '') === ' ') { + if ( + data.toString().replace(/\n/g, '').length === 0 || + data.toString().replace(/\n/g, '') === ' ' + ) { console.log('(Can not be blank.) Enter a name for your Application:'); } else { - createApp(data); - + createApp(data); } return true; } function buyNumberQuestion(data) { // console.log("data:", data); - if (data.toString().replace(/\n/g, '').length === 0 || data.toString().replace(/\n/g, '') === ' ') { + if ( + data.toString().replace(/\n/g, '').length === 0 || + data.toString().replace(/\n/g, '') === ' ' + ) { console.log('(Can not be blank.) Want to Buy a number? (Y/N):'); - } else if (data.toString().replace(/\n/g, '').toLowerCase() === 'y'){ - + } else if (data.toString().replace(/\n/g, '').toLowerCase() === 'y') { // process.env.VONAGE_API_SECRET = data.toString().replace(/\n/g, ''); step = 'SET_COUNTRY_CODE'; - console.log('Set the country code for your number (ex. US or GB):'); + console.log('Set the country code for your number (ex. US or GB):'); } else if (data.toString().replace(/\n/g, '').toLowerCase() === 'n') { // answered No to question - writeEnv(); + writeEnv(); } return true; } function setCountryCode(data) { - if (data.toString().replace(/\n/g, '').length === 0 || data.toString().replace(/\n/g, '') === ' ') { - console.log('(Can not be blank.) Set the country code for your number (ex. US or GB):'); + if ( + data.toString().replace(/\n/g, '').length === 0 || + data.toString().replace(/\n/g, '') === ' ' + ) { + console.log( + '(Can not be blank.) Set the country code for your number (ex. US or GB):' + ); } else { - buyPhoneNumber(data) + buyPhoneNumber(data); } return true; } -function buyPhoneNumber(data){ +function buyPhoneNumber(data) { const countryCode = data.toString().replace(/\n/g, ''); process.env.COUNTRY_CODE = data.toString().replace(/\n/g, '').toUpperCase(); //Search for a number console.log('Searching for a number in country: ', countryCode); - vonage.numbers.getAvailableNumbers({ + vonage.numbers + .getAvailableNumbers({ country: process.env.COUNTRY_CODE, features: ['VOICE', 'SMS'], - }) - .then((results) => { - const numbers = results.numbers; - console.log('Found numbers: ', numbers); - // Purchase a number - if (numbers.length === 0) { - console.log('No numbers found in this country. Please try another country code.'); - return; - } - console.log('Found a number: ', numbers[0].msisdn); - vonage.numbers.buyNumber({ - country: numbers[0].country, - msisdn: numbers[0].msisdn, }) - .then((result) => { - console.log('Bought the number!'); - updatePhoneNumber(numbers[0]); + .then((results) => { + const numbers = results.numbers; + console.log('Found numbers: ', numbers); + // Purchase a number + if (numbers.length === 0) { + console.log( + 'No numbers found in this country. Please try another country code.' + ); + return; + } + console.log('Found a number: ', numbers[0].msisdn); + vonage.numbers + .buyNumber({ + country: numbers[0].country, + msisdn: numbers[0].msisdn, + }) + .then((result) => { + console.log('Bought the number!'); + updatePhoneNumber(numbers[0]); + }) + .catch((error) => { + console.error('Error buying number:', error); + }); }) .catch((error) => { - console.error("Error buying number:", error); + console.error(error); }); - }) - .catch((error) => { - console.error(error) - }); } async function updatePhoneNumber(number) { @@ -161,56 +184,62 @@ async function updatePhoneNumber(number) { } else { console.log('Added number to application!'); process.env.VONAGE_PHONE_NUMBER = number.msisdn; - writeEnv(); + // writeEnv(); + sanitizeWorkshopEnvironment(); } } function createApp(data) { console.log('Creating your Application...'); - vonage = new Vonage({ - apiKey: process.env.VONAGE_API_KEY, - apiSecret: process.env.VONAGE_API_SECRET - }, { - debug: false - }); + vonage = new Vonage( + { + apiKey: process.env.VONAGE_API_KEY, + apiSecret: process.env.VONAGE_API_SECRET, + }, + { + debug: false, + } + ); - vonage.applications.createApplication({ + vonage.applications + .createApplication({ name: data.toString().replace(/\n/g, ''), capabilities: { - voice: { - webhooks: { - answer_url: { - address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/voice/answer`, - http_method: "GET" - }, - event_url: { - address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/voice/event`, - http_method: "POST" - } - } + voice: { + webhooks: { + answer_url: { + address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/voice/answer`, + http_method: 'GET', + }, + event_url: { + address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/voice/event`, + http_method: 'POST', + }, }, - messages: { - webhooks: { - inbound_url: { - address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/webhooks/inbound`, - http_method: "POST" - }, - status_url: { - address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/webhooks/status`, - http_method: "POST" - } - } + }, + messages: { + webhooks: { + inbound_url: { + address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/webhooks/inbound`, + http_method: 'POST', + }, + status_url: { + address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/webhooks/status`, + http_method: 'POST', + }, }, - rtc: { - webhooks: { - event_url: { - address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/webhooks/rtcevent`, - http_method: "POST" - } - } - } - } - }).then((app) => { + }, + rtc: { + webhooks: { + event_url: { + address: `https://${process.env.CODESPACE_NAME}-${PORT}.app.github.dev/webhooks/rtcevent`, + http_method: 'POST', + }, + }, + }, + }, + }) + .then((app) => { console.log('Application created with ID: ', app.id); process.env.API_APPLICATION_ID = app.id; fs.writeFile(__dirname + '/private.key', app.keys.private_key, (err) => { @@ -226,22 +255,22 @@ function createApp(data) { process.env.PRIVATE_KEY64 = base64PrivateKey; //Search and Buy phone number - process.env.VONAGE_APPLICATION_NAME = data.toString().replace(/\n/g, ''); + process.env.VONAGE_APPLICATION_NAME = data + .toString() + .replace(/\n/g, ''); step = 'BUY_NUMBER'; console.log('Want to Buy a number? (Y/N):'); - } catch (error) { console.error('An error occurred:', error); } - - } }); - }).catch((error) => { + }) + .catch((error) => { console.error('Error creating Application: ', error); process.exit(); - }); - return true; + }); + return true; } function writeEnv() { @@ -254,36 +283,74 @@ API_APPLICATION_ID="${process.env.API_APPLICATION_ID}" COUNTRY_CODE="${process.env.COUNTRY_CODE}" VONAGE_PHONE_NUMBER="${process.env.VONAGE_PHONE_NUMBER}" PRIVATE_KEY64="${process.env.PRIVATE_KEY64}"`; - + fs.writeFile(__dirname + '/.env', contents, (err) => { if (err) { - console.log('Error writing .env file: ',err); + console.log('Error writing .env file: ', err); } else { console.log('Environment variables saved to .env'); process.exit(); } }); - } function createUser() { - //create user - const vonage = new Vonage({ - apiKey: process.env.VONAGE_API_KEY, - apiSecret: process.env.VONAGE_API_SECRET, - applicationId: process.env.API_APPLICATION_ID, - privateKey: __dirname + process.env.PRIVATE_KEY - }, {debug: false}); - vonage.users.create({ + //create user + const vonage = new Vonage( + { + apiKey: process.env.VONAGE_API_KEY, + apiSecret: process.env.VONAGE_API_SECRET, + applicationId: process.env.API_APPLICATION_ID, + privateKey: __dirname + process.env.PRIVATE_KEY, + }, + { debug: false } + ); + vonage.users.create( + { name: process.env.ADMIN_NAME, - display_name: process.env.ADMIN_NAME - },(err, response) => { + display_name: process.env.ADMIN_NAME, + }, + (err, response) => { if (err) { - console.log('Error creating user: ',err); + console.log('Error creating user: ', err); } else { console.log('User created. ID: ', response.id); process.exit(); } - }); + } + ); +} + +// Allow coding exercise to be exported to user's GitHub account +function sanitizeWorkshopEnvironment() { + // Look for the parent git directory (one level up from the 'project' CWD) + const parentGitPath = path.join(__dirname, '../.git'); + const projectGitPath = path.join(__dirname, '.git'); + + try { + // 1. Remove any accidentally created git tracker inside the project folder + if (fs.existsSync(projectGitPath)) { + fs.rmSync(projectGitPath, { recursive: true, force: true }); + console.log('Cleared local .git directory to ensure a clean slate.'); + } -} \ No newline at end of file + // 2. Sever the tie with your main multi-workshop repository + if (fs.existsSync(parentGitPath)) { + // Renaming it prevents Git from looking upwards for tracking configurations, + // while preserving your workshop configuration integrity. + const backupPath = path.join(__dirname, '../.git_bak'); + if (!fs.existsSync(backupPath)) { + fs.renameSync(parentGitPath, backupPath); + console.log( + 'Successfully separated current workspace from the main repository tracking.' + ); + } + } + process.exit(); + } catch (error) { + console.error( + 'Warning: Failed to safely disconnect parent repository framework:', + error.message + ); + } +} diff --git a/tutorials/webxr-javascript-workshop/project/static/VonageAudioCall.js b/tutorials/webxr-javascript-workshop/project/static/VonageAudioCall.js index c044fdcd..2b0156b6 100644 --- a/tutorials/webxr-javascript-workshop/project/static/VonageAudioCall.js +++ b/tutorials/webxr-javascript-workshop/project/static/VonageAudioCall.js @@ -1,25 +1,44 @@ +import * as THREE from 'three'; import * as xb from 'xrblocks'; +import { LipsyncMouth } from 'lipsync'; +import { Keyboard } from 'xrblocks/addons/virtualkeyboard/Keyboard.js'; -export class VonageAudioCall extends xb.Script { +// ⌄⌄⌄ Set Quick Replies ⌄⌄⌄ +export class VonageAudioCall extends xb.Script { // ⌄⌄⌄ Create constructor ⌄⌄⌄ - - // ⌄⌄⌄ Create call panel ⌄⌄⌄ - - // ⌄⌄⌄ Update call controls ⌄⌄⌄ - - // ⌄⌄⌄ Remove call panel ⌄⌄⌄ - - // ⌄⌄⌄ Answer call method ⌄⌄⌄ - - // ⌄⌄⌄ Reject call method ⌄⌄⌄ - - // ⌄⌄⌄ Hang Up call method ⌄⌄⌄ - - // ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄ - - // ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ - - // ⌄⌄⌄ Initialize ⌄⌄⌄ - -} \ No newline at end of file + // ⌄⌄⌄ Create 3D Avatar ⌄⌄⌄ + // ⌄⌄⌄ Remove 3D Avatar ⌄⌄⌄ + // ⌄⌄⌄ Create Call panel ⌄⌄⌄ + // ⌄⌄⌄ Update Call controls ⌄⌄⌄ + // ⌄⌄⌄ Remove Call panel ⌄⌄⌄ + // ⌄⌄⌄ Show Virtual Keyboard ⌄⌄⌄ + // ⌄⌄⌄ Hide Virtual Keyboard ⌄⌄⌄ + // ⌄⌄⌄ Toggle Virtual Keyboard ⌄⌄⌄ + // ⌄⌄⌄ Send Quick Reply ⌄⌄⌄ + // ⌄⌄⌄ Send Custom Text ⌄⌄⌄ + // ⌄⌄⌄ Create Reply panel ⌄⌄⌄ + // ⌄⌄⌄ Remove Reply panel ⌄⌄⌄ + // ⌄⌄⌄ Answer call method ⌄⌄⌄ + // ⌄⌄⌄ Reject call method ⌄⌄⌄ + // ⌄⌄⌄ Hang Up call method ⌄⌄⌄ + // ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄ + // ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ + // ⌄⌄⌄ Initialize ⌄⌄⌄ + + // the update() method runs per frame. This allows the 3D Avatar to face the user as they move around + update() { + const head = this.puppetHead; + const cam = xb.core?.camera; + if (!head || !cam) return; + + cam.getWorldPosition(this._camWorld); + head.getWorldPosition(this._headWorld); + + // Mirror the camera through the head centre so local -Z faces the user + const targetX = 2 * this._headWorld.x - this._camWorld.x; + const targetZ = 2 * this._headWorld.z - this._camWorld.z; + // Clamp Y so the avatar only yaws — it won't pitch if you're taller/shorter + head.lookAt(targetX, this._headWorld.y, targetZ); + } +} diff --git a/tutorials/webxr-javascript-workshop/src/content/docs/04_Vonage_Call_Panel.md b/tutorials/webxr-javascript-workshop/src/content/docs/04_Vonage_Call_Panel.md index 2eda61a1..b32e40c8 100644 --- a/tutorials/webxr-javascript-workshop/src/content/docs/04_Vonage_Call_Panel.md +++ b/tutorials/webxr-javascript-workshop/src/content/docs/04_Vonage_Call_Panel.md @@ -3,12 +3,33 @@ title: Vonage Call Panel description: Create XR Blocks UI to answer phone calls --- -We'll be creating the UI to recieve phone calls via the Vonage Voice API using the XR Blocks library's SpatialPanel Class. +Now, we'll be creating the UI. + +To recieve phone calls via the Vonage Voice API using the XR Blocks library's SpatialPanel Class. + +To show the 3D Avatar for the caller, we will use the Lipsync (Addon). + +The Vonage Voice Client SDK's Text to Speech will be used to send the quick replies and typed messages into the call. + +The virtual keyboard that allows us to type those messages will come from the Virtual Keyboard (Addon). The following code will be placed in the `VonageAudioCall.js` file. -First, let's initiate the constructor for our panel with some variables: +First, we will set the Quick Replies that the user can send into the call. +Find `// ⌄⌄⌄ Set Quick Replies ⌄⌄⌄` and add this code: + +```js +const QUICK_REPLIES = [ + { label: "Meeting", message: "In a meeting, I'll call you back." }, + { label: "Talk Later", message: "Can't talk right now. I'll talk later." }, + { label: "OMW!", message: "On my way! Talk soon." }, + { label: "5 Mins", message: "Call you back in 5 minutes." }, +]; +``` + +Let's initiate the constructor for our panel with some variables: `// ⌄⌄⌄ Create constructor ⌄⌄⌄` + ```js constructor() { super(); @@ -16,23 +37,96 @@ constructor() { this.client = new vonageClientSDK.VonageClient(); this.callId = null; // Keep a reference to the panel so we can destroy it later - this.panel = null; + this.panel = null; this.statusText = null; this.userName = "XR_User_1"; this.grid = null; this.controlRow = null; + this.puppetHead = null; + this.face = null; + this.mouth = null; + this._camWorld = new THREE.Vector3(); + this._headWorld = new THREE.Vector3(); + this.replyPanel = null; + this.typedTextView = null; + this._currentTypedText = ''; + this.keyboard = null; +} +``` + +Here's the function to create an Avatar and add the MediaStream for the LipSync feature: `// ⌄⌄⌄ Create 3D Avatar ⌄⌄⌄` + +```js +_createAvatar(stream) { + // Safety: don't create a second avatar if one already exists + if (this.puppetHead) return; + + console.log("Creating lipsync avatar..."); + + const faceR = 0.1; + + const head = new THREE.Group(); + // Position: in front of the user, roughly at face height + head.position.set(0, xb.user.height, -1.2); + + // --- Sphere face mesh --- + const faceGeom = new THREE.SphereGeometry(faceR, 32, 24); + const faceMat = new THREE.MeshStandardMaterial({ + color: 0xf2d4b3, + roughness: 0.6, + metalness: 0.05, + }); + const faceMesh = new THREE.Mesh(faceGeom, faceMat); + head.add(faceMesh); + + this.face = new xb.StylizedFace({ showEyes: true }); + head.add(this.face); + + this.mouth = new LipsyncMouth(stream, { target: this.face }); + head.add(this.mouth); + + this.puppetHead = head; + this.add(head); +} +``` + +This function will remove the 3D Avatar when the call is over: +`// ⌄⌄⌄ Remove 3D Avatar ⌄⌄⌄` + +```js +_removeAvatar() { + if (!this.puppetHead) return; + + console.log("Removing lipsync avatar..."); + + if (this.mouth) { + // Detach from the head group before nulling the reference + this.mouth.parent?.remove(this.mouth); + this.mouth = null; + } + + if (this.face) { + this.face.parent?.remove(this.face); + // dispose() frees the underlying canvas/texture to avoid memory leaks + this.face.dispose(); + this.face = null; + } + + this.remove(this.puppetHead); + this.puppetHead = null; } ``` Here's the function to create the panel: -`// ⌄⌄⌄ Create call panel ⌄⌄⌄` +`// ⌄⌄⌄ Create Call panel ⌄⌄⌄` + ```js -createCallPanel(callerName) { +_createCallPanel(callerName) { // SAFETY: If a panel already exists, don't create another one. if (this.panel) return; console.log("Creating Call UI..."); - + // 1. Create the Panel this.panel = new xb.SpatialPanel({ backgroundColor: '#2b2b2baa' }); this.panel.position.set( @@ -57,7 +151,8 @@ createCallPanel(callerName) { ``` Function to update the call control section: -`// ⌄⌄⌄ Update call controls ⌄⌄⌄` +`// ⌄⌄⌄ Update Call controls ⌄⌄⌄` + ```js updateControlRow(state) { if (!this.grid) return; @@ -107,9 +202,10 @@ updateControlRow(state) { ``` This function will remove the panel once the call is over: -`// ⌄⌄⌄ Remove call panel ⌄⌄⌄` +`// ⌄⌄⌄ Remove Call panel ⌄⌄⌄` + ```js -removeCallPanel() { +_removeCallPanel() { if (this.panel) { console.log("Destroying Call UI..."); this.remove(this.panel); @@ -118,62 +214,287 @@ removeCallPanel() { this.statusText = null; this.controlRow = null; } + this._removeReplyPanel(); +} +``` + +Now, let's add the Virtual Keyboard that will allow us to send text messages that will be spoken into the call. + +Here's the code to show the Keyboard: +`// ⌄⌄⌄ Show Virtual Keyboard ⌄⌄⌄` + +```js +_showKeyboard() { + if (this.keyboard) return; + + this.keyboard = new Keyboard(); + // Position it below and aligned with the reply panel + this.keyboard.position.set( + 0, + xb.user.height - 1.35, + -xb.user.objectDistance + 1 + ); + this.add(this.keyboard); + + // Update the display on every keystroke + this.keyboard.onTextChanged = (text) => { + this._currentTypedText = text; + if (this.typedTextView) { + this.typedTextView.text = text.length > 0 ? text : 'Tap to type...'; + } + }; + + // Enter key sends immediately — same as tapping the Send button + this.keyboard.onEnterPressed = (text) => { + this._sendTypedText(); + }; +} +``` + +If we want to hide the Keyboard, here's the code: +`// ⌄⌄⌄ Hide Virtual Keyboard ⌄⌄⌄` + +```js +_hideKeyboard() { + if (!this.keyboard) return; + this.remove(this.keyboard); + this.keyboard = null; +} +``` + +To toggle between showing and hidding the keyboard, we have this code: +`// ⌄⌄⌄ Toggle Virtual Keyboard ⌄⌄⌄` + +```js +_toggleKeyboard() { + this.keyboard ? this._hideKeyboard() : this._showKeyboard(); +} +``` + +Let's create the functions that will send the text to be said into the call just in case we can't talk at that moment. + +To send the Quick Replies that we set before: +`// ⌄⌄⌄ Send Quick Reply ⌄⌄⌄` + +```js +_sendQuickReply(message) { + if (!this.callId) return; + console.log(`Sending quick reply: "${message}"`); + + // Give the user immediate visual feedback in the status bar + if (this.statusText) this.statusText.text = 'Sending...'; + + this.client.say(this.callId, message) + .then(() => { + console.log('Quick reply sent successfully.'); + if (this.statusText) this.statusText.text = `Sent: "${message}"`; + }) + .catch(err => { + console.error('say() error:', err); + if (this.statusText) this.statusText.text = 'Failed to send message.'; + }); +} +``` + +In the case we want to carry on the conversation but maybe can't speak (ie in a public space), we can send custom text: +`// ⌄⌄⌄ Send Custom Text ⌄⌄⌄` + +```js +_sendTypedText() { + const text = this._currentTypedText.trim(); + if (!text) return; + if (!this.callId) return; + + console.log(`Sending typed text: "${text}"`); + if (this.statusText) this.statusText.text = 'Sending...'; + + this.client.say(this.callId, text) + .then(() => { + console.log('Typed text sent successfully.'); + if (this.statusText) this.statusText.text = `Sent: "${text}"`; + + // Clear the keyboard buffer and reset the display + if (this.keyboard) this.keyboard.setText(''); + this._currentTypedText = ''; + if (this.typedTextView) this.typedTextView.text = 'Tap to type...'; + }) + .catch(err => { + console.error('say() error:', err); + if (this.statusText) this.statusText.text = 'Failed to send message.'; + }); +} +``` + +Here we will create the Reply panel that will hold all the way we can send a text message into the call: +`// ⌄⌄⌄ Create Reply panel ⌄⌄⌄` + +```js +_createReplyPanel() { + if (this.replyPanel) return; + + this.replyPanel = new xb.SpatialPanel({ + backgroundColor: '#1a1a2ecc', + width: .75, + height: 0.9, + }); + // Offset to the right so it sits beside the main call panel + this.replyPanel.position.set( + 0.8, + xb.user.height - 0.5, + -xb.user.objectDistance + ); + this.add(this.replyPanel); + + const grid = this.replyPanel.addGrid(); + + grid.addRow({ weight: 0.06 }).addText({ + text: 'Quick Replies', + fontColor: '#9b9bff', + fontSize: 0.055, + }); + + const pairs = [ + QUICK_REPLIES.slice(0, 2), // [ Meeting, Talk Later ] + QUICK_REPLIES.slice(2, 4), // [ OMW!, 5 Mins ] + ]; + + pairs.forEach(pair => { + const row = grid.addRow({ weight: 0.20 }); + pair.forEach(({ label, message }) => { + const btn = row.addCol({ weight: 0.5 }).addTextButton({ + text: label, + fontSize: 0.35, + backgroundColor: '#2e2e50', + fontColor: '#ffffff', + }); + btn.onTriggered = () => this._sendQuickReply(message); + }); + }); + + grid.addRow({ weight: 0.06 }).addText({ + text: 'Talk via Text', + fontColor: '#9b9bff', + fontSize: 0.055, + }); + + this.typedTextView = grid.addRow({ weight: 0.18 }).addText({ + text: 'Tap to type...', + fontColor: '#ffffff', + fontSize: 0.065, + textAlign: 'left', + }); + + const actionRow = grid.addRow({ weight: 0.30 }); + + const kbBtn = actionRow.addCol({ weight: 0.5 }).addIconButton({ + text: 'keyboard', + fontSize: 0.5, + backgroundColor: '#2e3a4a', + }); + kbBtn.onTriggered = () => this._toggleKeyboard(); + + const sendBtn = actionRow.addCol({ weight: 0.5 }).addIconButton({ + text: 'send', + fontSize: 0.5, + backgroundColor: '#1a4a2a', + }); + sendBtn.onTriggered = () => this._sendTypedText(); + + this.replyPanel.updateLayouts(); +} +``` + +Just like with the Call panel, we will have a function to remove the Reply panel: +`// ⌄⌄⌄ Remove Reply panel ⌄⌄⌄` + +```js +_removeReplyPanel() { + this._hideKeyboard(); + if (this.replyPanel) { + this.remove(this.replyPanel); + this.replyPanel = null; + this.typedTextView = null; + } + this._currentTypedText = ''; } ``` This function answers the call and updates the status and call control section: `// ⌄⌄⌄ Answer call method ⌄⌄⌄` + ```js _onAnswer() { console.log('Answering...'); this.client.answer(this.callId) - .then(() => { - console.log("Success answering call."); - this.statusText.text = `Call answered.`; - this.updateControlRow('CONNECTED'); - }) - .catch(error => { - console.error("Error answering call: ", error); - }); + .then(() => { + console.log("Success answering call."); + this.statusText.text = `Call answered.`; + this.updateControlRow('CONNECTED'); + + // ⌄⌄⌄ Show reply panel alongside the call panel ⌄⌄⌄ + this._createReplyPanel(); + + // get media stream + const audioElement = this.client.getAudioOutputElement(); + if (audioElement && audioElement.srcObject) { + // This is the active WebRTC MediaStream managed by Vonage + const remoteStream = audioElement.srcObject; + console.log('remoteStream: ', remoteStream); + + // Example: Grab individual audio tracks from the stream + const audioTracks = remoteStream.getAudioTracks(); + console.log("Active Audio Tracks:", audioTracks); + + // ⌄⌄⌄ Spin up the lipsync avatar driven by the remote stream ⌄⌄⌄ + this._createAvatar(remoteStream); + } + }) + .catch(error => { + console.error("Error answering call: ", error); + }); } ``` This function will reject the incoming call and remove the panel: `// ⌄⌄⌄ Reject call method ⌄⌄⌄` + ```js _onReject() { console.log('Rejecting...'); this.client.reject(this.callId) - .then(() => { - console.log("Success rejecting call."); - }) - .catch(error => { - console.error("Error rejecting call: ", error); - }); - // We manually destroy the panel here too, just in case the event lags - this.removeCallPanel(); + .then(() => { + console.log("Success rejecting call."); + }) + .catch(error => { + console.error("Error rejecting call: ", error); + }); + this._removeCallPanel(); + this._removeAvatar(); } ``` This function will hang up the ongoing call and remove the panel: `// ⌄⌄⌄ Hang Up call method ⌄⌄⌄ ` + ```js _onHangup() { console.log('Hanging up...'); this.client.hangup(this.callId) - .then(() => { - console.log("Success hanging up call."); - }) - .catch(error => { - console.error("Error hanging up call: ", error); - }); + .then(() => { + console.log("Success hanging up call."); + }) + .catch(error => { + console.error("Error hanging up call: ", error); + }); // We manually destroy the panel here too, just in case the event lags - this.removeCallPanel(); + this._removeCallPanel(); + this._removeAvatar(); } ``` Set up some listeners for the events that the Vonage Client SDK will emit and what to do: `// ⌄⌄⌄ Set Up Vonage Listeners ⌄⌄⌄` + ```js setupVonageListeners() { // --- CREATE UI ON INVITE --- @@ -181,9 +502,9 @@ setupVonageListeners() { this.callId = callId; const maskedNumber = from.replace(/\d(?=(?:\D*\d){4})/g, "*") console.log(`Incoming call from ${maskedNumber}`); - + // Trigger the UI creation here - this.createCallPanel(maskedNumber); + this._createCallPanel(maskedNumber); }); this.client.on('legStatusUpdate', (callId, legId, status) => { @@ -197,19 +518,22 @@ setupVonageListeners() { this.client.on('callInviteCancel', (callId) => { console.log(`Call cancelled: ${callId}`); this.callId = null; - this.removeCallPanel(); + this._removeCallPanel(); + this._removeAvatar(); }); this.client.on("callHangup", (callId, callQuality, reason) => { console.log(`Call hung up: ${reason}`); this.callId = null; - this.removeCallPanel(); + this._removeCallPanel(); + this._removeAvatar(); }); } ``` Get a token from the server so you can connect to a session: `// ⌄⌄⌄ Connect to server to get token ⌄⌄⌄ ` + ```js async connectToVonage(name) { try { @@ -217,7 +541,7 @@ async connectToVonage(name) { // 1. Fetch the token (AWAIT the result) const response = await fetch(`/token?name=${name}`); - + if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } @@ -228,7 +552,7 @@ async connectToVonage(name) { // 2. Create the Session (AWAIT the result) const sessionId = await this.client.createSession(this.token); - + console.log("Session created successfully. Session ID:", sessionId); // 3. Update UI @@ -246,6 +570,7 @@ async connectToVonage(name) { Initialize the Class when loaded into the page: `// ⌄⌄⌄ Initialize ⌄⌄⌄` + ```js init() { console.log("Vonage init!",this.client); diff --git a/tutorials/webxr-javascript-workshop/src/content/docs/07_Congrats.md b/tutorials/webxr-javascript-workshop/src/content/docs/07_Congrats.md index 4f04c053..3687cd40 100644 --- a/tutorials/webxr-javascript-workshop/src/content/docs/07_Congrats.md +++ b/tutorials/webxr-javascript-workshop/src/content/docs/07_Congrats.md @@ -7,8 +7,22 @@ description: What's next. You now have a WebXR application using XR Blocks and the Vonage Voice API that can receive phone calls. +## Export your application + +If you'd like to save the application you created to your personal GitHub acoount, open a new Terminal window (press the + button) and run this command: + +```bash +chmod +x export.sh && ./export.sh +``` + +## Create your own XR Blocks application with AI + +XR Blocks has a Google Gemini Gem, that allows you to create a WebXR application using just plain text. Want to create something? Give it a try. + ## What's Next? + - Can you create a WebXR application that makes phone calls? How about a voice chat in a WebXR environment? - Learn more about the Vonage Voice API in our developer documenation -- Connect with us on Twitter / X and LinkedIn -- Join our Developer Community Slack channel to connect with others building with Vonage \ No newline at end of file +- Want to learn more about other Vonage products? Try our interactive Learning Center and earn certificates. +- Connect with us on Twitter / X, Bluesky and LinkedIn +- Join our Developer Community Slack channel to connect with others building with Vonage diff --git a/tutorials/webxr-javascript-workshop/src/content/docs/index.mdx b/tutorials/webxr-javascript-workshop/src/content/docs/index.mdx index 91830be9..174791d7 100644 --- a/tutorials/webxr-javascript-workshop/src/content/docs/index.mdx +++ b/tutorials/webxr-javascript-workshop/src/content/docs/index.mdx @@ -1,7 +1,7 @@ --- -title: Vonage Voice API Workshop +title: CreateHer Fest description: Let's build some sample applications! template: splash hero: - tagline: Let's build some sample applications! + tagline: DIALED IN! Answer calls in WebXR. --- diff --git a/tutorials/webxr-javascript-workshop/steps/01_create_account/index.html b/tutorials/webxr-javascript-workshop/steps/01_create_account/index.html index bfd950fe..520c24d0 100644 --- a/tutorials/webxr-javascript-workshop/steps/01_create_account/index.html +++ b/tutorials/webxr-javascript-workshop/steps/01_create_account/index.html @@ -26,7 +26,7 @@ })(); Skip to content