| 
					
				 | 
			
			
				@@ -23,7 +23,6 @@ import { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   deleteSelectedElements, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   getElementsWithinSelection, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   isOverScrollBars, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  restoreFromLocalStorage, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   saveToLocalStorage, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   getElementAtPosition, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   createScene, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -32,9 +31,8 @@ import { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   hasStroke, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   hasText, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   exportCanvas, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  importFromBackend, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  addToLoadedScenes, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   loadedScenes, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  loadScene, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   calculateScrollCenter, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   loadFromBlob, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } from "./scene"; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -163,6 +161,7 @@ interface LayerUIProps { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   canvas: HTMLCanvasElement | null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   setAppState: any; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   elements: readonly ExcalidrawElement[]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  language: string; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   setElements: (elements: readonly ExcalidrawElement[]) => void; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -173,6 +172,7 @@ const LayerUI = React.memo( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     setAppState, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     canvas, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     elements, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    language, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     setElements, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }: LayerUIProps) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     function renderCanvasActions() { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -318,56 +318,101 @@ const LayerUI = React.memo( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function renderIdsDropdown() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const scenes = loadedScenes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (scenes.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <StoredScenesList 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          scenes={scenes} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          currentId={appState.selectedId} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          onChange={async (id, k) => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            actionManager.updater(await loadScene(id, k)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <FixedSideContainer side="top"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <div className="App-menu App-menu_top"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <Stack.Col gap={4} align="end"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <section 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              className="App-right-menu" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              aria-labelledby="canvas-actions-title" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <h2 className="visually-hidden" id="canvas-actions-title"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                {t("headings.canvasActions")} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              </h2> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <Island padding={4}>{renderCanvasActions()}</Island> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <FixedSideContainer side="top"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <div className="App-menu App-menu_top"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <Stack.Col gap={4} align="end"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <section 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                className="App-right-menu" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                aria-labelledby="canvas-actions-title" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <h2 className="visually-hidden" id="canvas-actions-title"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  {t("headings.canvasActions")} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </h2> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <Island padding={4}>{renderCanvasActions()}</Island> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </section> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <section 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                className="App-right-menu" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                aria-labelledby="selected-shape-title" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <h2 className="visually-hidden" id="selected-shape-title"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  {t("headings.selectedShapeActions")} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </h2> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                {renderSelectedShapeActions(elements)} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </section> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </Stack.Col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <section aria-labelledby="shapes-title"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <Stack.Col gap={4} align="start"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <Stack.Row gap={1}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <Island padding={1}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <h2 className="visually-hidden" id="shapes-title"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      {t("headings.shapes")} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    </h2> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <Stack.Row gap={1}>{renderShapesSwitcher()}</Stack.Row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  </Island> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <LockIcon 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    checked={appState.elementLocked} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    onChange={() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      setAppState({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        elementLocked: !appState.elementLocked, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        elementType: appState.elementLocked 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          ? "selection" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          : appState.elementType, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    title={t("toolBar.lock")} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </Stack.Row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </Stack.Col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </section> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <section 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              className="App-right-menu" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              aria-labelledby="selected-shape-title" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <div /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </FixedSideContainer> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <footer role="contentinfo"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <HintViewer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            elementType={appState.elementType} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            multiMode={appState.multiElement !== null} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            isResizing={appState.isResizing} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            elements={elements} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <LanguageList 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            onChange={lng => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              setLanguage(lng); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              setAppState({}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            languages={languages} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            currentLanguage={language} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          {renderIdsDropdown()} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          {appState.scrolledOutside && ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              className="scroll-back-to-content" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              onClick={() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                setAppState({ ...calculateScrollCenter(elements) }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <h2 className="visually-hidden" id="selected-shape-title"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                {t("headings.selectedShapeActions")} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              </h2> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              {renderSelectedShapeActions(elements)} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </section> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </Stack.Col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <section aria-labelledby="shapes-title"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <Stack.Col gap={4} align="start"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <Stack.Row gap={1}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <Island padding={1}> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <h2 className="visually-hidden" id="shapes-title"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    {t("headings.shapes")} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  </h2> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  <Stack.Row gap={1}>{renderShapesSwitcher()}</Stack.Row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                </Island> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                <LockIcon 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  checked={appState.elementLocked} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  onChange={() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    setAppState({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      elementLocked: !appState.elementLocked, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      elementType: appState.elementLocked 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        ? "selection" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        : appState.elementType, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  title={t("toolBar.lock")} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              </Stack.Row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </Stack.Col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </section> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <div /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </FixedSideContainer> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              {t("buttons.scrollBackToContent")} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          )} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </footer> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      </> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   (prev, next) => { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -390,6 +435,7 @@ const LayerUI = React.memo( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const keys = Object.keys(prevAppState) as (keyof Partial<AppState>)[]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      prev.language === next.language && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       prev.elements === next.elements && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       keys.every(k => prevAppState[k] === nextAppState[k]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -406,9 +452,6 @@ export class App extends React.Component<any, AppState> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     super(props); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     this.actionManager = new ActionManager( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       this.syncActionResult, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        history.resumeRecording(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       () => this.state, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       () => elements, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -443,13 +486,22 @@ export class App extends React.Component<any, AppState> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     this.canvasOnlyActions = [actionSelectAll]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  private syncActionResult = (res: ActionResult) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (res.elements !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  private syncActionResult = ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    res: ActionResult, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    commitToHistory: boolean = true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (res.elements) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       elements = res.elements; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (commitToHistory) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        history.resumeRecording(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       this.setState({}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (res.appState !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (res.appState) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (commitToHistory) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        history.resumeRecording(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       this.setState({ ...res.appState }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -478,32 +530,6 @@ export class App extends React.Component<any, AppState> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     this.saveDebounced.flush(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  private async loadScene(id: string | null, k: string | undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let selectedId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (id != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // k is the private key used to decrypt the content from the server, take 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // extra care not to leak it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      data = await importFromBackend(id, k); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      addToLoadedScenes(id, k); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      selectedId = id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      window.history.replaceState({}, "Excalidraw", window.location.origin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      data = restoreFromLocalStorage(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (data.elements) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      elements = data.elements; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (data.appState) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      history.resumeRecording(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.setState({ ...data.appState, selectedId }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.setState({}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   public async componentDidMount() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     document.addEventListener("copy", this.onCopy); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     document.addEventListener("paste", this.pasteFromClipboard); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -523,15 +549,15 @@ export class App extends React.Component<any, AppState> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (id) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       // Backwards compatibility with legacy url format 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.loadScene(id, undefined); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.syncActionResult(await loadScene(id)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       const match = window.location.hash.match( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /^#json=([0-9]+),([a-zA-Z0-9_-]+)$/, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if (match) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.loadScene(match[1], match[2]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.syncActionResult(await loadScene(match[1], match[2])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.loadScene(null, undefined); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.syncActionResult(await loadScene(null)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -572,13 +598,8 @@ export class App extends React.Component<any, AppState> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const actionResult = this.actionManager.handleKeyDown(event); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (actionResult) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.syncActionResult(actionResult); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (actionResult) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (this.actionManager.handleKeyDown(event)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const shape = findShapeByKey(event.key); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -750,6 +771,7 @@ export class App extends React.Component<any, AppState> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           actionManager={this.actionManager} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           elements={elements} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           setElements={this.setElements} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          language={getLanguage()} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         <main> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           <canvas 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1797,10 +1819,7 @@ export class App extends React.Component<any, AppState> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               if (file?.type === "application/json") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 loadFromBlob(file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                   .then(({ elements, appState }) => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    this.syncActionResult({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      elements, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      appState, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } as ActionResult), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    this.syncActionResult({ elements, appState }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                   ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                   .catch(err => console.error(err)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1809,52 +1828,10 @@ export class App extends React.Component<any, AppState> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             {t("labels.drawingCanvas")} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           </canvas> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         </main> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <footer role="contentinfo"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <HintViewer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            elementType={this.state.elementType} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            multiMode={this.state.multiElement !== null} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            isResizing={this.state.isResizing} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            elements={elements} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <LanguageList 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            onChange={lng => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              setLanguage(lng); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              this.setState({ lng }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            languages={languages} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            currentLanguage={getLanguage()} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          {this.renderIdsDropdown()} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          {this.state.scrolledOutside && ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              className="scroll-back-to-content" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              onClick={() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                this.setState({ ...calculateScrollCenter(elements) }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              {t("buttons.scrollBackToContent")} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          )} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </footer> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  private renderIdsDropdown() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const scenes = loadedScenes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (scenes.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <StoredScenesList 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        scenes={scenes} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        currentId={this.state.selectedId} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        onChange={(id, k) => this.loadScene(id, k)} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   private handleWheel = (e: WheelEvent) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     e.preventDefault(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const { deltaX, deltaY } = e; 
			 |