| 
					
				 | 
			
			
				@@ -18,6 +18,21 @@ const LOCAL_STORAGE_KEY_STATE = "excalidraw-state"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var elements = Array.of<ExcalidrawElement>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript/47593316#47593316 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const LCG = (seed: number) => () => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ((2 ** 31 - 1) & (seed = Math.imul(48271, seed))) / 2 ** 31; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Unfortunately, roughjs doesn't support a seed attribute (https://github.com/pshihn/rough/issues/27). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// We can achieve the same result by overriding the Math.random function with a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// pseudo random generator that supports a random seed and swapping it back after. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function withCustomMathRandom<T>(seed: number, cb: () => T): T { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const random = Math.random; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Math.random = LCG(seed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const result = cb(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Math.random = random; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // https://stackoverflow.com/a/6853926/232122 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function distanceBetweenPointAndSegment( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   x: number, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -126,6 +141,7 @@ function newElement( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     isSelected: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     strokeColor: strokeColor, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     backgroundColor: backgroundColor, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    seed: Math.floor(Math.random() * 2 ** 31), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     draw(rc: RoughCanvas, context: CanvasRenderingContext2D) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return element; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -307,22 +323,27 @@ function generateDraw(element: ExcalidrawElement) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       context.fillStyle = fillStyle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else if (element.type === "rectangle") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const shape = generator.rectangle(0, 0, element.width, element.height, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      stroke: element.strokeColor, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      fill: element.backgroundColor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const shape = withCustomMathRandom(element.seed, () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return generator.rectangle(0, 0, element.width, element.height, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        stroke: element.strokeColor, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fill: element.backgroundColor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     element.draw = (rc, context) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       context.translate(element.x, element.y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       rc.draw(shape); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       context.translate(-element.x, -element.y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else if (element.type === "ellipse") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const shape = generator.ellipse( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      element.width / 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      element.height / 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      element.width, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      element.height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      { stroke: element.strokeColor, fill: element.backgroundColor } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const shape = withCustomMathRandom(element.seed, () => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      generator.ellipse( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        element.width / 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        element.height / 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        element.width, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        element.height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { stroke: element.strokeColor, fill: element.backgroundColor } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     element.draw = (rc, context) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       context.translate(element.x, element.y); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -331,14 +352,14 @@ function generateDraw(element: ExcalidrawElement) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else if (element.type === "arrow") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const [x1, y1, x2, y2, x3, y3, x4, y4] = getArrowPoints(element); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const shapes = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const shapes = withCustomMathRandom(element.seed, () => [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       //    \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       generator.line(x3, y3, x2, y2, { stroke: element.strokeColor }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       // ----- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       generator.line(x1, y1, x2, y2, { stroke: element.strokeColor }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       //    / 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       generator.line(x4, y4, x2, y2, { stroke: element.strokeColor }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     element.draw = (rc, context) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       context.translate(element.x, element.y); 
			 |