diff options
| -rw-r--r-- | package-lock.json | 14 | ||||
| -rw-r--r-- | package.json | 1 | ||||
| -rw-r--r-- | src/.DS_Store | bin | 10244 -> 14340 bytes | |||
| -rw-r--r-- | src/client/apis/gpt/GPT.ts | 32 | ||||
| -rw-r--r-- | src/client/cognitive_services/CognitiveServices.ts | 11 | ||||
| -rw-r--r-- | src/client/documents/Documents.ts | 2 | ||||
| -rw-r--r-- | src/client/util/CurrentUserUtils.ts | 2 | ||||
| -rw-r--r-- | src/client/views/DocumentDecorations.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/GestureOverlay.tsx | 251 | ||||
| -rw-r--r-- | src/client/views/InkTranscription.scss | 5 | ||||
| -rw-r--r-- | src/client/views/InkTranscription.tsx | 781 | ||||
| -rw-r--r-- | src/client/views/InkingStroke.tsx | 4 | ||||
| -rw-r--r-- | src/client/views/MainView.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/global/globalScripts.ts | 6 | ||||
| -rw-r--r-- | src/client/views/nodes/DiagramBox.scss | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/DiagramBox.tsx | 130 | ||||
| -rw-r--r-- | src/client/views/nodes/ScreenshotBox.tsx | 2 | ||||
| -rw-r--r-- | src/pen-gestures/GestureTypes.ts | 1 | ||||
| -rw-r--r-- | src/pen-gestures/ndollar.ts | 2401 |
19 files changed, 3282 insertions, 367 deletions
diff --git a/package-lock.json b/package-lock.json index 1e738fcb1..e0cfeaed7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -127,6 +127,7 @@ "https": "^1.0.0", "https-browserify": "^1.0.0", "i": "^0.3.7", + "iink-ts": "^1.0.5", "image-data-uri": "^2.0.1", "image-size": "^1.0.2", "image-size-stream": "^1.1.0", @@ -20291,6 +20292,14 @@ "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" }, + "node_modules/iink-ts": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/iink-ts/-/iink-ts-1.0.5.tgz", + "integrity": "sha512-LAWWPvgcsLtouI9ExVijZbPGIWMfJtVCcuznbIDyboaPb+cHYsftcuJdjDU7TQwIpGP4hmcjNQA57XPCw4MK2A==", + "dependencies": { + "json-css": "^1.5.6" + } + }, "node_modules/image-data-uri": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/image-data-uri/-/image-data-uri-2.0.1.tgz", @@ -21759,6 +21768,11 @@ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, + "node_modules/json-css": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/json-css/-/json-css-1.5.6.tgz", + "integrity": "sha512-B/0T0OxZH9tSb93tXV6VOYtXqrPz/Vgz2QrCT/4NXen8HGElYkYr9V+8IrSVTMj/ftxa8cG1kcu7f3iAMlaFlQ==" + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", diff --git a/package.json b/package.json index 81ee9972a..cfe10d02f 100644 --- a/package.json +++ b/package.json @@ -206,6 +206,7 @@ "https": "^1.0.0", "https-browserify": "^1.0.0", "i": "^0.3.7", + "iink-ts": "^1.0.5", "image-data-uri": "^2.0.1", "image-size": "^1.0.2", "image-size-stream": "^1.1.0", diff --git a/src/.DS_Store b/src/.DS_Store Binary files differindex 426a2ee90..19eea5fce 100644 --- a/src/.DS_Store +++ b/src/.DS_Store diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index 8dd3fd6e2..6f1956558 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -149,5 +149,35 @@ const gptImageLabel = async (src: string): Promise<string> => { return 'Error connecting with API'; } }; +const gptHandwriting = async (src: string): Promise<string> => { + try { + const response = await openai.chat.completions.create({ + model: 'gpt-4o', + temperature: 0, + messages: [ + { + role: 'user', + content: [ + { type: 'text', text: 'What is this does this handwriting say. Only return the text' }, + { + type: 'image_url', + image_url: { + url: `${src}`, + detail: 'low', + }, + }, + ], + }, + ], + }); + if (response.choices[0].message.content) { + return response.choices[0].message.content; + } + return 'Missing labels'; + } catch (err) { + console.log(err); + return 'Error connecting with API'; + } +}; -export { gptAPICall, gptImageCall, GPTCallType, gptImageLabel, gptGetEmbedding }; +export { gptAPICall, gptImageCall, GPTCallType, gptImageLabel, gptGetEmbedding, gptHandwriting }; diff --git a/src/client/cognitive_services/CognitiveServices.ts b/src/client/cognitive_services/CognitiveServices.ts index 9808b6a01..9f46b8685 100644 --- a/src/client/cognitive_services/CognitiveServices.ts +++ b/src/client/cognitive_services/CognitiveServices.ts @@ -46,14 +46,15 @@ export enum Confidence { export namespace CognitiveServices { const ExecuteQuery = async <D>(service: Service, manager: APIManager<D>, data: D): Promise<any> => { const apiKey = process.env[service.toUpperCase()]; - if (!apiKey) { + if (apiKey) { + console.log(data) console.log(`No API key found for ${service}: ensure youe root directory has .env file with _CLIENT_${service.toUpperCase()}.`); return undefined; } let results: any; try { - results = await manager.requester(apiKey, manager.converter(data), service).then(json => JSON.parse(json)); + results = await manager.requester("has", manager.converter(data), service).then(json => JSON.parse(json)); } catch (e) { throw e; } @@ -137,6 +138,12 @@ export namespace CognitiveServices { points: points.map(({ X: x, Y: y }) => `${x},${y}`).join(','), language: 'en-US', })); + console.log(JSON.stringify({ + version: 1, + language: 'en-US', + unit: 'mm', + strokes, + })) return JSON.stringify({ version: 1, language: 'en-US', diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index af181b031..19d914a6a 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -773,7 +773,7 @@ export namespace Docs { export function ComparisonDocument(text: string, options: DocumentOptions = { title: 'Comparison Box' }) { return InstanceFromProto(Prototypes.get(DocumentType.COMPARISON), text, options); } - export function DiagramDocument(options: DocumentOptions = { title: 'bruh box' }) { + export function DiagramDocument(options: DocumentOptions = { title: '' }) { return InstanceFromProto(Prototypes.get(DocumentType.DIAGRAM), undefined, options); } diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 14fb65252..e2ced1786 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -392,7 +392,7 @@ pie title Minerals in my tap water { toolTip: "Tap or drag to create a plotly node", title: "Plotly", icon: "rocket", dragFactory: doc.emptyPlotly as Doc, clickFactory: DocCast(doc.emptyMermaids)}, { toolTip: "Tap or drag to create a physics simulation",title: "Simulation", icon: "rocket",dragFactory: doc.emptySimulation as Doc, clickFactory: DocCast(doc.emptySimulation), funcs: { hidden: "IsNoviceMode()"}}, { toolTip: "Tap or drag to create a note board", title: "Notes", icon: "book", dragFactory: doc.emptyNoteboard as Doc, clickFactory: DocCast(doc.emptyNoteboard)}, - { toolTip: "Tap or drag to create an iamge", title: "Image", icon: "image", dragFactory: doc.emptyImage as Doc, clickFactory: DocCast(doc.emptyImage)}, + { toolTip: "Tap or drag to create an image", title: "Image", icon: "image", dragFactory: doc.emptyImage as Doc, clickFactory: DocCast(doc.emptyImage)}, { toolTip: "Tap or drag to create a collection", title: "Col", icon: "folder", dragFactory: doc.emptyCollection as Doc, clickFactory: DocCast(doc.emptyTab)}, { toolTip: "Tap or drag to create a webpage", title: "Web", icon: "globe-asia", dragFactory: doc.emptyWebpage as Doc, clickFactory: DocCast(doc.emptyWebpage)}, { toolTip: "Tap or drag to create a comparison box", title: "Compare", icon: "columns", dragFactory: doc.emptyComparison as Doc, clickFactory: DocCast(doc.emptyComparison)}, diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index da35459bb..09c9936a5 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -878,4 +878,4 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora </div> ); } -} +}
\ No newline at end of file diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 3a2738c3b..0c797adf2 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -7,6 +7,7 @@ import { emptyFunction } from '../../Utils'; import { Doc, Opt, returnEmptyDoclist } from '../../fields/Doc'; import { InkData, InkField, InkTool } from '../../fields/InkField'; import { NumCast } from '../../fields/Types'; +import { Docs } from '../documents/Documents'; import { ActiveArrowEnd, ActiveArrowScale, @@ -30,7 +31,10 @@ import './GestureOverlay.scss'; import { ObservableReactComponent } from './ObservableReactComponent'; import { returnEmptyDocViewList } from './StyleProvider'; import { ActiveFillColor, DocumentView } from './nodes/DocumentView'; - +import { CollectionFreeFormView } from './collections/collectionFreeForm'; +import { InkingStroke } from './InkingStroke'; +import { NullLiteral } from 'typescript'; +import { isNull } from 'lodash'; export enum ToolglassTools { InkToText = 'inktotext', IgnoreGesture = 'ignoregesture', @@ -127,8 +131,136 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil // SetActiveArrowEnd('none'); } } + isScribble(inkPoints: any) { + const ffView = DocumentView.allViews().find(view => view.ComponentView instanceof CollectionFreeFormView); + const points = this._points.map(p => ({ X: p.X, Y: p.Y })); + const cuspArray = this.getNumberOfCusps(points); + let cuspBooleanArray: boolean[] = []; + let docsToDelete: Doc[] = []; + const childDocs = (ffView?.ComponentView as CollectionFreeFormView).childDocs; + childDocs.filter(doc => doc.type === 'ink').map(doc => DocumentView.getDocumentView(doc, DocumentView.getDocumentView(doc))); + if ((ffView?.ComponentView as CollectionFreeFormView).childDocs) { + if (cuspArray.length > 4) { + console.log('there are enough cusps'); + for (let i = 0; i < cuspArray.length - 2; i++) { + let hasDocInTriangle = false; + for (let doc of childDocs) { + const point1 = cuspArray[i]; + const point2 = cuspArray[i + 1]; + const point3 = cuspArray[i + 2]; + const triangleObject = { p1: { X: point1.X, Y: point1.Y }, p2: { X: point2.X, Y: point2.Y }, p3: { X: point3.X, Y: point3.Y } }; + const otherInk = DocumentView.getDocumentView(doc)?.ComponentView as InkingStroke; + const { inkData: otherInkData } = otherInk?.inkScaledData() ?? { inkData: [] }; + const otherScreenPts = otherInkData.map(point => otherInk.ptToScreen(point)); + console.log(otherScreenPts); + console.log((DocumentView.getDocumentView(doc)?.ComponentView as InkingStroke).inkScaledData().inkData.map(point => ({ X: point.X, Y: point.Y }))); + console.log(triangleObject); + if (doc.title === 'line') { + if (this.doesLineIntersectTriangle(otherScreenPts, triangleObject)) { + docsToDelete.push(doc); + hasDocInTriangle = true; + cuspBooleanArray.push(true); + } + } else { + if (this.isAnyPointInTriangle(triangleObject, otherScreenPts)) { + docsToDelete.push(doc); + hasDocInTriangle = true; + cuspBooleanArray.push(true); + } + } + } + cuspBooleanArray.push(hasDocInTriangle); + } + if (this.determineIfScribble(cuspBooleanArray)) { + docsToDelete.forEach(doc => { + ffView?.ComponentView?.removeDocument?.(doc); + }); + this._points = []; + return true; + } + } + } + return false; + } + determineIfScribble(cuspBooleanArray: boolean[]) { + if (!cuspBooleanArray) { + return false; + } + const quarterArrayLength = Math.ceil((cuspBooleanArray.length - 2) * 0.25); + let hasObjectInFirstAndLast25 = true; + for (let i = 0; i < quarterArrayLength; i++) { + if (cuspBooleanArray[i] == false || cuspBooleanArray[cuspBooleanArray.length - 1 - i] == false) { + hasObjectInFirstAndLast25 = false; + } + } + console.log(cuspBooleanArray); + console.log(hasObjectInFirstAndLast25); + const trueCount = cuspBooleanArray.filter(value => value).length; + const percentageTrues = trueCount / cuspBooleanArray.length; + if (percentageTrues > 0.65 || hasObjectInFirstAndLast25) { + console.log('requirements are met'); + } + return percentageTrues > 0.65 || hasObjectInFirstAndLast25; + } + isRectangleOverlap(rect1: any, rect2: any): boolean { + const noOverlap = rect1.maxX < rect2.minX || rect1.minX > rect2.maxX || rect1.maxY < rect2.minY || rect1.minY > rect2.maxY; + + return !noOverlap; + } + isPointInTriangle(pt: { X: number; Y: number }, triangle: any): boolean { + const area = (v1: { X: number; Y: number }, v2: { X: number; Y: number }, v3: { X: number; Y: number }) => Math.abs((v1.X * (v2.Y - v3.Y) + v2.X * (v3.Y - v1.Y) + v3.X * (v1.Y - v2.Y)) / 2.0); + + const A = area(triangle.p1, triangle.p2, triangle.p3); + + const A1 = area(pt, triangle.p2, triangle.p3); + const A2 = area(triangle.p1, pt, triangle.p3); + const A3 = area(triangle.p1, triangle.p2, pt); + + return A === A1 + A2 + A3; + } + isAnyPointInTriangle(triangle: any, points: any[]): boolean { + for (const point of points) { + //console.log(point.X + ' ' + point.Y); + //console.log(triangle); + if (this.isPointInTriangle(point, triangle)) { + return true; + } + } + return false; + } + doesLineIntersectTriangle(line: any, triangle: any): boolean { + const edges = [ + { start: triangle.p1, end: triangle.p2 }, + { start: triangle.p2, end: triangle.p3 }, + { start: triangle.p3, end: triangle.p1 }, + ]; + + for (const edge of edges) { + if (this.doLinesIntersect(line, edge)) { + return true; + } + } + + return false; + } + doLinesIntersect(line1: any, line2: any): boolean { + const A = line1[0]; + const B = line1[line1.length - 1]; + const { start: C, end: D } = line2; + const denominator = (B.X - A.X) * (D.Y - C.Y) - (B.Y - A.Y) * (D.X - C.X); + if (denominator === 0) return false; + + const numerator1 = (A.Y - C.Y) * (D.X - C.X) - (A.X - C.X) * (D.Y - C.Y); + const numerator2 = (A.Y - C.Y) * (B.X - A.X) - (A.X - C.X) * (B.Y - A.Y); + + const r = numerator1 / denominator; + const s = numerator2 / denominator; + + return r >= 0 && r <= 1 && s >= 0 && s <= 1; + } @action onPointerUp = () => { + console.log('pointer up'); DocumentView.DownDocView = undefined; if (this._points.length > 1) { const B = this.svgBounds; @@ -145,6 +277,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil // need to decide when to turn gestures back on const result = points.length > 2 && GestureUtils.GestureRecognizer.Recognize([points]); let actionPerformed = false; + //console.log(result); if (Doc.UserDoc().recognizeGestures && result && result.Score > 0.7) { switch (result.Name) { case Gestures.Line: @@ -153,14 +286,24 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil case Gestures.Circle: this.makeBezierPolygon(result.Name, true); actionPerformed = this.dispatchGesture(result.Name); + console.log(result.Name); + console.log(); break; case Gestures.Scribble: console.log('scribble'); break; + case Gestures.RightAngle: + this.convertToText(); + this._points = []; + console.log('RightAngle'); + return; default: } } - + if (this.isScribble(points)) { + this._points = []; + return; + } // if no gesture (or if the gesture was unsuccessful), "dry" the stroke into an ink document if (!actionPerformed) { const newPoints = this._points.reduce((p, pts) => { @@ -190,7 +333,111 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil } this._points.length = 0; }; + convertToText() { + const ffView = DocumentView.allViews().find(view => view.ComponentView instanceof CollectionFreeFormView); + let docsToBeConverted: Doc[] = []; + let minX = 999999999; + let maxX = -999999999; + let minY = 999999999; + let maxY = -999999999; + (ffView?.ComponentView as CollectionFreeFormView).childDocs + .filter(doc => doc.type === 'collection') + .forEach(doc => { + if (typeof doc.width === 'number' && typeof doc.height === 'number' && typeof doc.x === 'number' && typeof doc.y === 'number') { + const bounds = DocumentView.getDocumentView(doc)?.getBounds; + console.log(DocumentView.getDocumentView(doc)); + console.log(bounds); + if (bounds) { + const rect1 = { minX: bounds.left, maxX: bounds.right, minY: bounds.top, maxY: bounds.bottom }; + console.log(rect1); + console.log(this.getExtremeCoordinates(this._points)); + const points = this._points.map(p => ({ X: p.X, Y: p.Y })); + console.log(points); + if (this.isRectangleOverlap(rect1, this.getExtremeCoordinates(this._points))) { + if (doc.x < minX) { + minX = doc.x; + } + if (doc.x > maxX) { + maxX = doc.x; + } + if (doc.y < minY) { + minY = doc.y; + } + if (doc.y + doc.height > maxY) { + maxY = doc.y + doc.height; + } + const newDoc = Docs.Create.TextDocument(doc.transcription as string, { title: '', x: doc.x as number, y: minY }); + newDoc.height = doc.height; + newDoc.width = doc.width; + if (ffView?.ComponentView?.addDocument && ffView?.ComponentView?.removeDocument) { + ffView.ComponentView.addDocument(newDoc); + ffView.ComponentView.removeDocument(doc); + } + //docsToBeConverted.push(doc); + } + } + } + }); + // const collectionDoc = Docs.Create.FreeformDocument(docsToBeConverted, { title: '', x: minX as number, y: maxY as number }); + // collectionDoc.height = 50; + // collectionDoc.width = 50; + // if (ffView?.ComponentView?.addDocument) { + // ffView.ComponentView.addDocument(collectionDoc); + // } + // DocumentView.getDocumentView(collectionDoc)?.ComponentView?.updateIcon; + // const newDoc = Docs.Create.TextDocument(doc.transcription as string, { title: '', x: doc.x as number, y: maxY }); + // newDoc.height = 50; + // if (ffView?.ComponentView?.addDocument) { + // ffView.ComponentView.addDocument(newDoc); + // } + } + getNumberOfCusps(points: any) { + let arrayOfPoints: any[] = []; + arrayOfPoints.push(points[0]); + for (let i = 0; i < points.length - 2; i++) { + const point1 = points[i]; + const point2 = points[i + 1]; + const point3 = points[i + 2]; + // console.log(point1); + // console.log(point2); + // console.log(point3); + // console.log(this.find_angle(point1, point2, point3)); + if (this.find_angle(point1, point2, point3) < 90) { + arrayOfPoints.push(point2); + } + } + arrayOfPoints.push(points[points.length - 1]); + return arrayOfPoints; + } + getExtremeCoordinates(coordinates: any[]) { + if (coordinates.length === 0) { + throw new Error('Coordinates array is empty'); + } + let minX = coordinates[0].X; + let maxX = coordinates[0].X; + let minY = coordinates[0].Y; + let maxY = coordinates[0].Y; + + coordinates.forEach(coord => { + if (coord.X < minX) minX = coord.X; + if (coord.X > maxX) maxX = coord.X; + if (coord.Y < minY) minY = coord.Y; + if (coord.Y > maxY) maxY = coord.Y; + }); + return { + minX, + maxX, + minY, + maxY, + }; + } + find_angle(A: any, B: any, C: any) { + let AB = Math.sqrt(Math.pow(B.X - A.X, 2) + Math.pow(B.Y - A.Y, 2)); + let BC = Math.sqrt(Math.pow(B.X - C.X, 2) + Math.pow(B.Y - C.Y, 2)); + let AC = Math.sqrt(Math.pow(C.X - A.X, 2) + Math.pow(C.Y - A.Y, 2)); + return Math.acos((BC * BC + AB * AB - AC * AC) / (2 * BC * AB)) * (180 / Math.PI); + } makeBezierPolygon = (shape: string, gesture: boolean) => { const xs = this._points.map(p => p.X); const ys = this._points.map(p => p.Y); diff --git a/src/client/views/InkTranscription.scss b/src/client/views/InkTranscription.scss index bbb0a1afa..18d6b8b10 100644 --- a/src/client/views/InkTranscription.scss +++ b/src/client/views/InkTranscription.scss @@ -2,4 +2,9 @@ .error-msg { display: none !important; } + .ms-editor{ + .smartguide{ + top:1000px; + } + } }
\ No newline at end of file diff --git a/src/client/views/InkTranscription.tsx b/src/client/views/InkTranscription.tsx index 33db72960..93f054462 100644 --- a/src/client/views/InkTranscription.tsx +++ b/src/client/views/InkTranscription.tsx @@ -1,350 +1,431 @@ -// import * as iink from 'iink-js'; -// import { action, observable } from 'mobx'; -// import * as React from 'react'; -// import { Doc, DocListCast } from '../../fields/Doc'; -// import { InkData, InkField, InkTool } from '../../fields/InkField'; -// import { Cast, DateCast, NumCast } from '../../fields/Types'; -// import { aggregateBounds } from '../../Utils'; -// import { DocumentType } from '../documents/DocumentTypes'; -// import { CollectionFreeFormView } from './collections/collectionFreeForm'; -// import { InkingStroke } from './InkingStroke'; -// import './InkTranscription.scss'; - -// /** -// * Class component that handles inking in writing mode -// */ -// export class InkTranscription extends React.Component { -// static Instance: InkTranscription; - -// @observable _mathRegister: any= undefined; -// @observable _mathRef: any= undefined; -// @observable _textRegister: any= undefined; -// @observable _textRef: any= undefined; -// private lastJiix: any; -// private currGroup?: Doc; - -// constructor(props: Readonly<{}>) { -// super(props); - -// InkTranscription.Instance = this; -// } - -// componentWillUnmount() { -// this._mathRef.removeEventListener('exported', (e: any) => this.exportInk(e, this._mathRef)); -// this._textRef.removeEventListener('exported', (e: any) => this.exportInk(e, this._textRef)); -// } - -// @action -// setMathRef = (r: any) => { -// if (!this._mathRegister) { -// this._mathRegister = r -// ? iink.register(r, { -// recognitionParams: { -// type: 'MATH', -// protocol: 'WEBSOCKET', -// server: { -// host: 'cloud.myscript.com', -// applicationKey: process.env.IINKJS_APP, -// hmacKey: process.env.IINKJS_HMAC, -// websocket: { -// pingEnabled: false, -// autoReconnect: true, -// }, -// }, -// iink: { -// math: { -// mimeTypes: ['application/x-latex', 'application/vnd.myscript.jiix'], -// }, -// export: { -// jiix: { -// strokes: true, -// }, -// }, -// }, -// }, -// }) -// : null; -// } - -// r?.addEventListener('exported', (e: any) => this.exportInk(e, this._mathRef)); - -// return (this._mathRef = r); -// }; - -// @action -// setTextRef = (r: any) => { -// if (!this._textRegister) { -// this._textRegister = r -// ? iink.register(r, { -// recognitionParams: { -// type: 'TEXT', -// protocol: 'WEBSOCKET', -// server: { -// host: 'cloud.myscript.com', -// applicationKey: '7277ec34-0c2e-4ee1-9757-ccb657e3f89f', -// hmacKey: 'f5cb18f2-1f95-4ddb-96ac-3f7c888dffc1', -// websocket: { -// pingEnabled: false, -// autoReconnect: true, -// }, -// }, -// iink: { -// text: { -// mimeTypes: ['text/plain'], -// }, -// export: { -// jiix: { -// strokes: true, -// }, -// }, -// }, -// }, -// }) -// : null; -// } - -// r?.addEventListener('exported', (e: any) => this.exportInk(e, this._textRef)); - -// return (this._textRef = r); -// }; - -// /** -// * Handles processing Dash Doc data for ink transcription. -// * -// * @param groupDoc the group which contains the ink strokes we want to transcribe -// * @param inkDocs the ink docs contained within the selected group -// * @param math boolean whether to do math transcription or not -// */ -// transcribeInk = (groupDoc: Doc | undefined, inkDocs: Doc[], math: boolean) => { -// if (!groupDoc) return; -// const validInks = inkDocs.filter(s => s.type === DocumentType.INK); - -// const strokes: InkData[] = []; -// const times: number[] = []; -// validInks -// .filter(i => Cast(i[Doc.LayoutFieldKey(i)], InkField)) -// .forEach(i => { -// const d = Cast(i[Doc.LayoutFieldKey(i)], InkField, null); -// const inkStroke = DocumentManager.Instance.getDocumentView(i)?.ComponentView as InkingStroke; -// strokes.push(d.inkData.map(pd => inkStroke.ptToScreen({ X: pd.X, Y: pd.Y }))); -// times.push(DateCast(i.author_date).getDate().getTime()); -// }); - -// this.currGroup = groupDoc; - -// const pointerData = { events: strokes.map((stroke, i) => this.inkJSON(stroke, times[i])) }; -// const processGestures = false; - -// if (math) { -// this._mathRef.editor.pointerEvents(pointerData, processGestures); -// } else { -// this._textRef.editor.pointerEvents(pointerData, processGestures); -// } -// }; - -// /** -// * Converts the Dash Ink Data to JSON. -// * -// * @param stroke The dash ink data -// * @param time the time of the stroke -// * @returns json object representation of ink data -// */ -// inkJSON = (stroke: InkData, time: number) => { -// return { -// pointerType: 'PEN', -// pointerId: 1, -// x: stroke.map(point => point.X), -// y: stroke.map(point => point.Y), -// t: new Array(stroke.length).fill(time), -// p: new Array(stroke.length).fill(1.0), -// }; -// }; - -// /** -// * Creates subgroups for each word for the whole text transcription -// * @param wordInkDocMap the mapping of words to ink strokes (Ink Docs) -// */ -// subgroupsTranscriptions = (wordInkDocMap: Map<string, Doc[]>) => { -// // iterate through the keys of wordInkDocMap -// wordInkDocMap.forEach(async (inkDocs: Doc[], word: string) => { -// const selected = inkDocs.slice(); -// if (!selected) { -// return; -// } -// const ctx = await Cast(selected[0].embedContainer, Doc); -// if (!ctx) { -// return; -// } -// const docView: CollectionFreeFormView = DocumentManager.Instance.getDocumentView(ctx)?.ComponentView as CollectionFreeFormView; - -// if (!docView) return; -// const marqViewRef = docView._marqueeViewRef.current; -// if (!marqViewRef) return; -// this.groupInkDocs(selected, docView, word); -// }); -// }; - -// /** -// * Event listener function for when the 'exported' event is heard. -// * -// * @param e the event objects -// * @param ref the ref to the editor -// */ -// exportInk = (e: any, ref: any) => { -// const exports = e.detail.exports; -// if (exports) { -// if (exports['application/x-latex']) { -// const latex = exports['application/x-latex']; -// if (this.currGroup) { -// this.currGroup.text = latex; -// this.currGroup.title = latex; -// } - -// ref.editor.clear(); -// } else if (exports['text/plain']) { -// if (exports['application/vnd.myscript.jiix']) { -// this.lastJiix = JSON.parse(exports['application/vnd.myscript.jiix']); -// // map timestamp to strokes -// const timestampWord = new Map<number, string>(); -// this.lastJiix.words.map((word: any) => { -// if (word.items) { -// word.items.forEach((i: { id: string; timestamp: string; X: Array<number>; Y: Array<number>; F: Array<number> }) => { -// const ms = Date.parse(i.timestamp); -// timestampWord.set(ms, word.label); -// }); -// } -// }); - -// const wordInkDocMap = new Map<string, Doc[]>(); -// if (this.currGroup) { -// const docList = DocListCast(this.currGroup.data); -// docList.forEach((inkDoc: Doc) => { -// // just having the times match up and be a unique value (actual timestamp doesn't matter) -// const ms = DateCast(inkDoc.author_date).getDate().getTime() + 14400000; -// const word = timestampWord.get(ms); -// if (!word) { -// return; -// } -// const entry = wordInkDocMap.get(word); -// if (entry) { -// entry.push(inkDoc); -// wordInkDocMap.set(word, entry); -// } else { -// const newEntry = [inkDoc]; -// wordInkDocMap.set(word, newEntry); -// } -// }); -// if (this.lastJiix.words.length > 1) this.subgroupsTranscriptions(wordInkDocMap); -// } -// } -// const text = exports['text/plain']; - -// if (this.currGroup) { -// this.currGroup.text = text; // transcription text -// this.currGroup.icon_fieldKey = 'transcription'; // use the transcription icon template when iconifying -// this.currGroup.title = text.split('\n')[0]; -// } - -// ref.editor.clear(); -// } -// } -// }; - -// /** -// * Creates the ink grouping once the user leaves the writing mode. -// */ -// createInkGroup() { -// // TODO nda - if document being added to is a inkGrouping then we can just add to that group -// if (Doc.ActiveTool === InkTool.Write) { -// CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => { -// // TODO: nda - will probably want to go through ffView unprocessed docs and then see if any of the inksToGroup docs are in it and only use those -// const selected = ffView.unprocessedDocs; -// const newCollection = this.groupInkDocs( -// selected.filter(doc => doc.embedContainer), -// ffView -// ); -// ffView.unprocessedDocs = []; - -// InkTranscription.Instance.transcribeInk(newCollection, selected, false); -// }); -// } -// CollectionFreeFormView.collectionsWithUnprocessedInk.clear(); -// } - -// /** -// * Creates the groupings for a given list of ink docs on a specific doc view -// * @param selected: the list of ink docs to create a grouping of -// * @param docView: the view in which we want the grouping to be created -// * @param word: optional param if the group we are creating is a word (subgrouping individual words) -// * @returns a new collection Doc or undefined if the grouping fails -// */ -// groupInkDocs(selected: Doc[], docView: CollectionFreeFormView, word?: string): Doc | undefined { -// const bounds: { x: number; y: number; width?: number; height?: number }[] = []; - -// // calculate the necessary bounds from the selected ink docs -// selected.map( -// action(d => { -// const x = NumCast(d.x); -// const y = NumCast(d.y); -// const width = NumCast(d._width); -// const height = NumCast(d._height); -// bounds.push({ x, y, width, height }); -// }) -// ); - -// // calculate the aggregated bounds -// const aggregBounds = aggregateBounds(bounds, 0, 0); -// const marqViewRef = docView._marqueeViewRef.current; - -// // set the vals for bounds in marqueeView -// if (marqViewRef) { -// marqViewRef._downX = aggregBounds.x; -// marqViewRef._downY = aggregBounds.y; -// marqViewRef._lastX = aggregBounds.r; -// marqViewRef._lastY = aggregBounds.b; -// } - -// // map through all the selected ink strokes and create the groupings -// selected.map( -// action(d => { -// const dx = NumCast(d.x); -// const dy = NumCast(d.y); -// delete d.x; -// delete d.y; -// delete d.activeFrame; -// delete d._timecodeToShow; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection -// delete d._timecodeToHide; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection -// // calculate pos based on bounds -// if (marqViewRef?.Bounds) { -// d.x = dx - marqViewRef.Bounds.left - marqViewRef.Bounds.width / 2; -// d.y = dy - marqViewRef.Bounds.top - marqViewRef.Bounds.height / 2; -// } -// return d; -// }) -// ); -// docView.props.removeDocument?.(selected); -// // Gets a collection based on the selected nodes using a marquee view ref -// const newCollection = marqViewRef?.getCollection(selected, undefined, true); -// if (newCollection) { -// newCollection.width = NumCast(newCollection._width); -// newCollection.height = NumCast(newCollection._height); -// // if the grouping we are creating is an individual word -// if (word) { -// newCollection.title = word; -// } -// } - -// // nda - bug: when deleting a stroke before leaving writing mode, delete the stroke from unprocessed ink docs -// newCollection && docView.props.addDocument?.(newCollection); -// return newCollection; -// } - -// render() { -// return ( -// <div className="ink-transcription"> -// <div className="math-editor" ref={this.setMathRef} touch-action="none"></div> -// <div className="text-editor" ref={this.setTextRef} touch-action="none"></div> -// </div> -// ); -// } -// } +import * as iink from 'iink-ts'; +import { action, observable } from 'mobx'; +import * as React from 'react'; +import { Doc, DocListCast } from '../../fields/Doc'; +import { InkData, InkField, InkTool } from '../../fields/InkField'; +import { Cast, DateCast, ImageCast, NumCast, StrCast } from '../../fields/Types'; +import { aggregateBounds } from '../../Utils'; +import { DocumentType } from '../documents/DocumentTypes'; +import { CollectionFreeFormView } from './collections/collectionFreeForm'; +import { InkingStroke } from './InkingStroke'; +import './InkTranscription.scss'; +import { Docs } from '../documents/Documents'; +import { DocumentView } from './nodes/DocumentView'; +import { Number } from 'mongoose'; +import { NumberArray } from 'd3'; +import { ImageField } from '../../fields/URLField'; +import { gptHandwriting } from '../apis/gpt/GPT'; +import * as fs from 'fs'; +import { URLField } from '../../fields/URLField'; +/** + * Class component that handles inking in writing mode + */ +export class InkTranscription extends React.Component { + static Instance: InkTranscription; + + @observable _mathRegister: any = undefined; + @observable _mathRef: any = undefined; + @observable _textRegister: any = undefined; + @observable _textRef: any = undefined; + @observable iinkEditor: any = undefined; + private lastJiix: any; + private currGroup?: Doc; + private collectionFreeForm?: CollectionFreeFormView; + + constructor(props: Readonly<{}>) { + super(props); + + InkTranscription.Instance = this; + } + + componentWillUnmount() { + // this._mathRef.removeEventListener('exported', (e: any) => this.exportInk(e, this._mathRef)); + // this._textRef.removeEventListener('exported', (e: any) => this.exportInk(e, this._textRef)); + } + + @action + setMathRef = async (r: any) => { + if (!this._textRegister && r) { + let editor; + const options = { + configuration: { + server: { + scheme: 'https', + host: 'cloud.myscript.com', + applicationKey: 'c0901093-5ac5-4454-8e64-0def0f13f2ca', + hmacKey: 'f6465cca-1856-4492-a6a4-e2395841be2f', + protocol: 'WEBSOCKET', + }, + recognition: { + type: 'TEXT', + }, + }, + }; + + editor = new iink.Editor(r, options as any); + + await editor.initialize(); + + this._textRegister = r; + r?.addEventListener('exported', (e: any) => this.exportInk(e, this._textRef)); + + return (this._textRef = r); + } + }; + @action + setTextRef = async (r: any) => { + if (!this._textRegister && r) { + let editor; + const options = { + configuration: { + server: { + scheme: 'https', + host: 'cloud.myscript.com', + applicationKey: 'c0901093-5ac5-4454-8e64-0def0f13f2ca', + hmacKey: 'f6465cca-1856-4492-a6a4-e2395841be2f', + protocol: 'WEBSOCKET', + }, + recognition: { + type: 'TEXT', + }, + }, + }; + + editor = new iink.Editor(r, options as any); + + await editor.initialize(); + this.iinkEditor = editor; + this._textRegister = r; + r?.addEventListener('exported', (e: any) => this.exportInk(e, this._textRef)); + + return (this._textRef = r); + } + }; + + /** + * Handles processing Dash Doc data for ink transcription. + * + * @param groupDoc the group which contains the ink strokes we want to transcribe + * @param inkDocs the ink docs contained within the selected group + * @param math boolean whether to do math transcription or not + */ + transcribeInk = (groupDoc: Doc | undefined, inkDocs: Doc[], math: boolean) => { + if (!groupDoc) return; + const validInks = inkDocs.filter(s => s.type === DocumentType.INK); + + const strokes: InkData[] = []; + + const times: number[] = []; + validInks + .filter(i => Cast(i[Doc.LayoutFieldKey(i)], InkField)) + .forEach(i => { + const d = Cast(i[Doc.LayoutFieldKey(i)], InkField, null); + const inkStroke = DocumentView.getDocumentView(i)?.ComponentView as InkingStroke; + strokes.push(d.inkData.map(pd => inkStroke.ptToScreen({ X: pd.X, Y: pd.Y }))); + times.push(DateCast(i.author_date).getDate().getTime()); + }); + console.log(strokes); + console.log( + `this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + ` + + this.convertPointsToString(strokes) + + ` + ]) + ) + ) + ` + ); + //console.log(this.convertPointsToString(strokes)); + //console.log(this.convertPointsToString2(strokes)); + this.currGroup = groupDoc; + const pointerData = strokes.map((stroke, i) => this.inkJSON(stroke, times[i])); + const processGestures = false; + if (math) { + console.log('math'); + this.iinkEditor.importPointEvents(pointerData); + } else { + this.iinkEditor.importPointEvents(pointerData); + } + }; + convertPointsToString(points: InkData[]): string { + return points[0].map(point => `new Point(${point.X}, ${point.Y})`).join(','); + } + convertPointsToString2(points: InkData[]): string { + return points[0].map(point => `(${point.X},${point.Y})`).join(','); + } + + /** + * Converts the Dash Ink Data to JSON. + * + * @param stroke The dash ink data + * @param time the time of the stroke + * @returns json object representation of ink data + */ + inkJSON = (stroke: InkData, time: number) => { + interface strokeData { + x: number; + y: number; + t: number; + p: number; + } + let strokeObjects: strokeData[] = []; + stroke.forEach(point => { + let tempObject: strokeData = { + x: point.X, + y: point.Y, + t: time, + p: 1.0, + }; + strokeObjects.push(tempObject); + }); + return { + pointerType: 'PEN', + pointerId: 1, + pointers: strokeObjects, + }; + }; + + /** + * Creates subgroups for each word for the whole text transcription + * @param wordInkDocMap the mapping of words to ink strokes (Ink Docs) + */ + subgroupsTranscriptions = (wordInkDocMap: Map<string, Doc[]>) => { + // iterate through the keys of wordInkDocMap + wordInkDocMap.forEach(async (inkDocs: Doc[], word: string) => { + const selected = inkDocs.slice(); + if (!selected) { + return; + } + const ctx = await Cast(selected[0].embedContainer, Doc); + if (!ctx) { + return; + } + const docView: CollectionFreeFormView = DocumentView.getDocumentView(ctx)?.ComponentView as CollectionFreeFormView; + // DocumentManager.Instance.getDocumentView(ctx)?.ComponentView as CollectionFreeFormView; + + if (!docView) return; + const marqViewRef = docView._marqueeViewRef.current; + if (!marqViewRef) return; + this.groupInkDocs(selected, docView, word); + }); + }; + + /** + * Event listener function for when the 'exported' event is heard. + * + * @param e the event objects + * @param ref the ref to the editor + */ + exportInk = async (e: any, ref: any) => { + const exports = e.detail['application/vnd.myscript.jiix']; + if (exports) { + if (exports['type'] == 'Math') { + const latex = exports['application/x-latex']; + if (this.currGroup) { + this.currGroup.text = latex; + this.currGroup.title = latex; + } + + ref.editor.clear(); + } else if (exports['type'] == 'Text') { + if (exports['application/vnd.myscript.jiix']) { + this.lastJiix = JSON.parse(exports['application/vnd.myscript.jiix']); + // map timestamp to strokes + const timestampWord = new Map<number, string>(); + this.lastJiix.words.map((word: any) => { + if (word.items) { + word.items.forEach((i: { id: string; timestamp: string; X: Array<number>; Y: Array<number>; F: Array<number> }) => { + const ms = Date.parse(i.timestamp); + timestampWord.set(ms, word.label); + }); + } + }); + + const wordInkDocMap = new Map<string, Doc[]>(); + if (this.currGroup) { + const docList = DocListCast(this.currGroup.data); + docList.forEach((inkDoc: Doc) => { + // just having the times match up and be a unique value (actual timestamp doesn't matter) + const ms = DateCast(inkDoc.author_date).getDate().getTime() + 14400000; + const word = timestampWord.get(ms); + if (!word) { + return; + } + const entry = wordInkDocMap.get(word); + if (entry) { + entry.push(inkDoc); + wordInkDocMap.set(word, entry); + } else { + const newEntry = [inkDoc]; + wordInkDocMap.set(word, newEntry); + } + }); + if (this.lastJiix.words.length > 1) this.subgroupsTranscriptions(wordInkDocMap); + } + } + const text = exports['label']; + + if (this.currGroup && text) { + DocumentView.getDocumentView(this.currGroup)?.ComponentView?.updateIcon?.(); + let image = await this.getIcon(); + const pathname = image?.url.href as string; + console.log(image?.url); + console.log(image); + const { href } = (image as URLField).url; + const hrefParts = href.split('.'); + const hrefComplete = `${hrefParts[0]}_o.${hrefParts[1]}`; + let response; + try { + const hrefBase64 = await this.imageUrlToBase64(hrefComplete); + response = await gptHandwriting(hrefBase64); + console.log(response); + } catch (error) { + console.log('bad things have happened'); + } + const textBoxText = 'iink: ' + text + '\n' + '\n' + 'ChatGPT: ' + response; + this.currGroup.transcription = response; + this.currGroup.title = response; + if (!this.currGroup.hasTextBox) { + const newDoc = Docs.Create.TextDocument(textBoxText, { title: '', x: this.currGroup.x as number, y: (this.currGroup.y as number) + (this.currGroup.height as number) }); + newDoc.height = 200; + this.collectionFreeForm?.addDocument(newDoc); + this.currGroup.hasTextBox = true; + } + ref.editor.clear(); + } + } + } + }; + async getIcon() { + const docView = DocumentView.getDocumentView(this.currGroup); + console.log(this.currGroup); + if (docView) { + console.log(docView); + docView.ComponentView?.updateIcon?.(); + return new Promise<ImageField | undefined>(res => setTimeout(() => res(ImageCast(docView.Document.icon)), 1000)); + } + return undefined; + } + imageUrlToBase64 = async (imageUrl: string): Promise<string> => { + try { + const response = await fetch(imageUrl); + const blob = await response.blob(); + + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.readAsDataURL(blob); + reader.onloadend = () => resolve(reader.result as string); + reader.onerror = error => reject(error); + }); + } catch (error) { + console.error('Error:', error); + throw error; + } + }; + + /** + * Creates the ink grouping once the user leaves the writing mode. + */ + createInkGroup() { + // TODO nda - if document being added to is a inkGrouping then we can just add to that group + if (Doc.ActiveTool === InkTool.Write) { + CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => { + // TODO: nda - will probably want to go through ffView unprocessed docs and then see if any of the inksToGroup docs are in it and only use those + const selected = ffView.unprocessedDocs; + const newCollection = this.groupInkDocs( + selected.filter(doc => doc.embedContainer), + ffView + ); + ffView.unprocessedDocs = []; + + InkTranscription.Instance.transcribeInk(newCollection, selected, false); + }); + } + CollectionFreeFormView.collectionsWithUnprocessedInk.clear(); + } + + /** + * Creates the groupings for a given list of ink docs on a specific doc view + * @param selected: the list of ink docs to create a grouping of + * @param docView: the view in which we want the grouping to be created + * @param word: optional param if the group we are creating is a word (subgrouping individual words) + * @returns a new collection Doc or undefined if the grouping fails + */ + groupInkDocs(selected: Doc[], docView: CollectionFreeFormView, word?: string): Doc | undefined { + this.collectionFreeForm = docView; + const bounds: { x: number; y: number; width?: number; height?: number }[] = []; + + // calculate the necessary bounds from the selected ink docs + selected.map( + action(d => { + const x = NumCast(d.x); + const y = NumCast(d.y); + const width = NumCast(d._width); + const height = NumCast(d._height); + bounds.push({ x, y, width, height }); + }) + ); + + // calculate the aggregated bounds + const aggregBounds = aggregateBounds(bounds, 0, 0); + const marqViewRef = docView._marqueeViewRef.current; + + // set the vals for bounds in marqueeView + if (marqViewRef) { + marqViewRef._downX = aggregBounds.x; + marqViewRef._downY = aggregBounds.y; + marqViewRef._lastX = aggregBounds.r; + marqViewRef._lastY = aggregBounds.b; + } + + // map through all the selected ink strokes and create the groupings + selected.map( + action(d => { + const dx = NumCast(d.x); + const dy = NumCast(d.y); + delete d.x; + delete d.y; + delete d.activeFrame; + delete d._timecodeToShow; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection + delete d._timecodeToHide; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection + // calculate pos based on bounds + if (marqViewRef?.Bounds) { + d.x = dx - marqViewRef.Bounds.left - marqViewRef.Bounds.width / 2; + d.y = dy - marqViewRef.Bounds.top - marqViewRef.Bounds.height / 2; + } + return d; + }) + ); + docView.props.removeDocument?.(selected); + // Gets a collection based on the selected nodes using a marquee view ref + const newCollection = marqViewRef?.getCollection(selected, undefined, true); + if (newCollection) { + newCollection.width = NumCast(newCollection._width); + newCollection.height = NumCast(newCollection._height); + // if the grouping we are creating is an individual word + if (word) { + newCollection.title = word; + } + } + + // nda - bug: when deleting a stroke before leaving writing mode, delete the stroke from unprocessed ink docs + newCollection && docView.props.addDocument?.(newCollection); + if (newCollection) { + newCollection.hasTextBox = false; + } + return newCollection; + } + + render() { + return ( + <div className="ink-transcription"> + <div className="math-editor" ref={this.setMathRef} touch-action="none"></div> + <div className="text-editor" ref={this.setTextRef} touch-action="none"></div> + </div> + ); + } +} diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 2e82371cb..887e10027 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -107,8 +107,8 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>() * analyzes the ink stroke and saves the analysis of the stroke to the 'inkAnalysis' field, * and the recognized words to the 'handwriting' */ - analyzeStrokes() { - const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? []; + analyzeStrokes=()=> { + const data: InkData = this.inkScaledData().inkData ?? []; CognitiveServices.Inking.Appliers.ConcatenateHandwriting(this.dataDoc, ['inkAnalysis', 'handwriting'], [data]); } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 9f1c7da3d..7deca234e 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -74,6 +74,7 @@ import { PresBox } from './nodes/trails'; import { AnchorMenu } from './pdf/AnchorMenu'; import { GPTPopup } from './pdf/GPTPopup/GPTPopup'; import { TopBar } from './topbar/TopBar'; +import { InkTranscription } from './InkTranscription'; // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports const { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } = require('./global/globalCssVariables.module.scss'); // prettier-ignore @@ -1081,6 +1082,7 @@ export class MainView extends ObservableReactComponent<object> { <MarqueeOptionsMenu /> <TimelineMenu /> <RichTextMenu /> + <InkTranscription /> {this.snapLines} <LightboxView key="lightbox" PanelWidth={this._windowWidth} addSplit={CollectionDockingView.AddSplit} PanelHeight={this._windowHeight} maxBorder={this.lightboxMaxBorder} /> <GPTPopup key="gptpopup" /> diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index 2c7920bdd..f46b66840 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -36,6 +36,7 @@ import { ImageBox } from '../nodes/ImageBox'; import { VideoBox } from '../nodes/VideoBox'; import { WebBox } from '../nodes/WebBox'; import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; +import { InkTranscription } from '../InkTranscription'; // import { InkTranscription } from '../InkTranscription'; @@ -366,6 +367,7 @@ ScriptingGlobals.add(function toggleCharStyle(charStyle: attrname, checkResult?: export function createInkGroup(/* inksToGroup?: Doc[], isSubGroup?: boolean */) { // TODO nda - if document being added to is a inkGrouping then we can just add to that group if (Doc.ActiveTool === InkTool.Write) { + console.log('create inking group '); CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => { // TODO: nda - will probably want to go through ffView unprocessed docs and then see if any of the inksToGroup docs are in it and only use those const selected = ffView.unprocessedDocs; @@ -423,14 +425,14 @@ export function createInkGroup(/* inksToGroup?: Doc[], isSubGroup?: boolean */) // TODO: nda - will probably need to go through and only remove the unprocessed selected docs ffView.unprocessedDocs = []; - // InkTranscription.Instance.transcribeInk(newCollection, selected, false); + InkTranscription.Instance.transcribeInk(newCollection, selected, false); }); } CollectionFreeFormView.collectionsWithUnprocessedInk.clear(); } function setActiveTool(tool: InkTool | Gestures, keepPrim: boolean, checkResult?: boolean) { - // InkTranscription.Instance?.createInkGroup(); + InkTranscription.Instance?.createInkGroup(); if (checkResult) { return (Doc.ActiveTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool ? GestureOverlay.Instance?.KeepPrimitiveMode || ![Gestures.Circle, Gestures.Line, Gestures.Rectangle].includes(tool as Gestures) diff --git a/src/client/views/nodes/DiagramBox.scss b/src/client/views/nodes/DiagramBox.scss index 323638bff..b43f961d0 100644 --- a/src/client/views/nodes/DiagramBox.scss +++ b/src/client/views/nodes/DiagramBox.scss @@ -1,5 +1,3 @@ -$searchbarHeight: 50px; - .DIYNodeBox { width: 100%; height: 100%; diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 36deb2d8d..79cf39152 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -1,3 +1,5 @@ +/* eslint-disable prettier/prettier */ +/* eslint-disable jsx-a11y/control-has-associated-label */ import mermaid from 'mermaid'; import { action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; @@ -35,12 +37,23 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { super(props); makeObservable(this); } - + @observable renderDiv: React.ReactNode; + @observable inputValue = ''; + @observable createInputValue = ''; + @observable loading = false; + @observable errorMessage = ''; + @observable mermaidCode = ''; + @observable isExampleMenuOpen = false; @observable _showCode = false; @observable _inputValue = ''; @observable _generating = false; @observable _errorMessage = ''; + @action handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => { + this.inputValue = e.target.value; + console.log(e.target.value); + }; + @computed get mermaidcode() { return Cast(this.Document[DocData].text, RichTextField, null)?.Text ?? ''; } @@ -50,7 +63,9 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { mermaid.initialize({ securityLevel: 'loose', startOnLoad: true, - flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, + darkMode: true, + flowchart: { useMaxWidth: false, htmlLabels: true, curve: 'cardinal' }, + gantt: { useMaxWidth: true, useWidth: 2000 }, }); // when a new doc/text/ink/shape is created in the freeform view, this generates the corresponding mermaid diagram code reaction( @@ -197,6 +212,117 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { </div> ); } + exampleButton = () => { + if (this.isExampleMenuOpen) { + this.isExampleMenuOpen = false; + } else { + this.isExampleMenuOpen = true; + } + }; + flowButton = () => { + this.createInputValue = `flowchart TD + A[Christmas] -->|Get money| B(Go shopping) + B --> C{Let me think} + C -->|One| D[Laptop] + C -->|Two| E[iPhone] + C -->|Three| F[fa:fa-car Car]`; + }; + pieButton = () => { + this.createInputValue = `pie title Pets adopted by volunteers + "Dogs" : 386 + "Cats" : 85 + "Rats" : 15`; + }; + timelineButton = () => { + this.createInputValue = `gantt + title A Gantt Diagram + dateFormat YYYY-MM-DD + section Section + A task :a1, 2014-01-01, 30d + Another task :after a1 , 20d + section Another + Task in sec :2014-01-12 , 12d + another task : 24d`; + }; + classButton = () => { + this.createInputValue = `classDiagram + Animal <|-- Duck + Animal <|-- Fish + Animal <|-- Zebra + Animal : +int age + Animal : +String gender + Animal: +isMammal() + Animal: +mate() + class Duck{ + +String beakColor + +swim() + +quack() + } + class Fish{ + -int sizeInFeet + -canEat() + } + class Zebra{ + +bool is_wild + +run() + }`; + }; + mindmapButton = () => { + this.createInputValue = `mindmap + root((mindmap)) + Origins + Long history + ::icon(fa fa-book) + Popularisation + British popular psychology author Tony Buzan + Research + On effectivness<br/>and features + On Automatic creation + Uses + Creative techniques + Strategic planning + Argument mapping + Tools + Pen and paper + Mermaid`; + }; + handleInputChangeEditor = (e: React.ChangeEvent<HTMLTextAreaElement>) => { + if (typeof e.target.value === 'string') { + this.createInputValue = e.target.value; + } + }; + removeWhitespace(str: string): string { + return str.replace(/\s+/g, ''); + } + autoResize(element: HTMLTextAreaElement): void { + element.style.height = '5px'; + element.style.height = element.scrollHeight + 'px'; + } + timeline = `gantt + title College Timeline + dateFormat YYYY-MM-DD + section Semester 1 + Orientation :done, des1, 2023-08-01, 2023-08-03 + Classes Start :active, des2, 2023-08-04, 2023-12-15 + Midterm Exams : des3, 2023-10-15, 2023-10-20 + End of Semester : des4, 2023-12-16, 2023-12-20 + section Semester 2 + Classes Start : des5, 2024-01-10, 2024-05-15 + Spring Break : des6, 2024-03-15, 2024-03-22 + Midterm Exams : des7, 2024-03-25, 2024-03-30 + Final Exams : des8, 2024-05-10, 2024-05-15 + section Summer Break + Internship : des9, 2024-06-01, 2024-08-31 + section Semester 3 + Classes Start : des10, 2024-09-01, 2025-12-15 + Midterm Exams : des11, 2024-11-15, 2024-11-20 + End of Semester : des12, 2025-12-16, 2025-12-20 + section Semester 4 + Classes Start : des13, 2025-01-10, 2025-05-15 + Spring Break : des14, 2025-03-15, 2025-03-22 + Midterm Exams : des15, 2025-03-25, 2025-03-30 + Final Exams : des16, 2025-05-10, 2025-05-15 + Graduation : des17, 2025-05-20, 2025-05-21`; } Docs.Prototypes.TemplateMap.set(DocumentType.DIAGRAM, { diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 6289470b6..fd1c791d3 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -149,7 +149,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>() componentDidMount() { this.dataDoc.nativeWidth = this.dataDoc.nativeHeight = 0; - this._props.setContentViewBox?.(this); // this tells the DocumentView that this ScreenshotBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link. + this._props.setContentViewBox?.(this); // this tells the DocumentView that this Box is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link. // this.layoutDoc.videoWall && reaction(() => ({ width: this._props.PanelWidth(), height: this._props.PanelHeight() }), // ({ width, height }) => { // if (this._camera) { diff --git a/src/pen-gestures/GestureTypes.ts b/src/pen-gestures/GestureTypes.ts index d86562580..2e1c9d16f 100644 --- a/src/pen-gestures/GestureTypes.ts +++ b/src/pen-gestures/GestureTypes.ts @@ -7,6 +7,7 @@ export enum Gestures { Circle = 'circle', Rectangle = 'rectangle', Arrow = 'arrow', + RightAngle = 'rightangle', } // Defines a point in an ink as a pair of x- and y-coordinates. diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts index ff7f7310b..b0c9b38fc 100644 --- a/src/pen-gestures/ndollar.ts +++ b/src/pen-gestures/ndollar.ts @@ -209,6 +209,7 @@ export class NDollarRecognizer { ]) ) ); + this.Multistrokes.push(new Multistroke(Gestures.Rectangle, useBoundedRotationInvariance, new Array([new Point(30, 143), new Point(106, 146), new Point(106, 225), new Point(30, 222), new Point(30, 146)]))); this.Multistrokes.push(new Multistroke(Gestures.Line, useBoundedRotationInvariance, [[new Point(12, 347), new Point(119, 347)]])); this.Multistrokes.push( new Multistroke( @@ -219,6 +220,13 @@ export class NDollarRecognizer { ); this.Multistrokes.push( new Multistroke( + Gestures.Triangle, // equilateral + useBoundedRotationInvariance, + new Array([new Point(42, 100), new Point(140, 102), new Point(100, 200), new Point(40, 100)]) + ) + ); + this.Multistrokes.push( + new Multistroke( Gestures.Circle, useBoundedRotationInvariance, new Array([ @@ -236,6 +244,2399 @@ export class NDollarRecognizer { ]) ) ); + this.Multistrokes.push( + new Multistroke( + Gestures.Circle, + useBoundedRotationInvariance, + new Array([ + new Point(201, 250), + new Point(160, 230), + new Point(151, 210), + new Point(151, 190), + new Point(160, 170), + new Point(200, 150), + new Point(240, 170), + new Point(248, 190), + new Point(248, 210), + new Point(240, 230), + new Point(200, 250), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(276.00781250000006, 497.4101562500016), + new Point(280.60286458333337, 469.89583333333496), + new Point(282.5374434655979, 441.8024770298834), + new Point(289.79296875000006, 414.86718750000165), + new Point(289.79296875000006, 414.86718750000165), + new Point(292.5124798464027, 404.7713204345522), + new Point(289.79296875000006, 435.77864583333496), + new Point(289.79296875000006, 446.23437500000165), + new Point(289.79296875000006, 446.23437500000165), + new Point(289.79296875000006, 465.3946947286762), + new Point(282.9445447228653, 485.5602044229528), + new Point(289.08203125000006, 503.7109375000016), + new Point(289.08203125000006, 503.7109375000016), + new Point(291.5698015422837, 511.06816009146735), + new Point(290.1888930773859, 488.1832986718201), + new Point(291.62500000000006, 480.55078125000165), + new Point(291.62500000000006, 480.55078125000165), + new Point(293.73685011794026, 469.326872665182), + new Point(322.59517150931146, 346.2773826117464), + new Point(332.58593750000006, 361.54687500000165), + new Point(332.58593750000006, 361.54687500000165), + new Point(336.72267765843037, 367.8693053742304), + new Point(335.03501658569274, 426.14756287892226), + new Point(334.97265625000006, 428.85546875000165), + new Point(334.97265625000006, 428.85546875000165), + new Point(334.75057696287826, 438.4989352060781), + new Point(327.1299829154695, 464.9702683268237), + new Point(333.53515625000006, 457.75781250000165), + new Point(333.53515625000006, 457.75781250000165), + new Point(348.04703414039284, 441.4169154185076), + new Point(343.0473428072587, 415.7335041223468), + new Point(355.58984375000006, 398.17578125000165), + new Point(355.58984375000006, 398.17578125000165), + new Point(356.378948441255, 397.07114657231085), + new Point(359.56537318829993, 396.6848394178869), + new Point(359.66015625000006, 398.03906250000165), + new Point(359.66015625000006, 398.03906250000165), + new Point(361.2044201777204, 420.10289772841446), + new Point(360.77237763601187, 451.84025999124106), + new Point(358.19921875000006, 476.5546875000016), + new Point(358.19921875000006, 476.5546875000016), + new Point(357.6070961055013, 482.2418497865259), + new Point(354.42934859187244, 499.09978331452874), + new Point(355.03515625000006, 493.41406250000165), + new Point(355.03515625000006, 493.41406250000165), + new Point(355.53691935291783, 488.70483692329145), + new Point(372.96806232778727, 409.1807440286115), + new Point(381.04687500000006, 421.88281250000165), + new Point(381.04687500000006, 421.88281250000165), + new Point(384.3115812501151, 427.0158096383767), + new Point(382.95970673841725, 492.87966086931465), + new Point(378.03906250000006, 502.00781250000165), + new Point(378.03906250000006, 502.00781250000165), + new Point(377.1380156934775, 503.6793196193478), + new Point(376.64840733168273, 498.2870671159759), + new Point(376.96093750000006, 496.41406250000165), + new Point(376.96093750000006, 496.41406250000165), + new Point(379.5601031158967, 480.8371688437296), + new Point(386.93711122312965, 419.81283026955094), + new Point(401.41015625000006, 393.99218750000165), + new Point(401.41015625000006, 393.99218750000165), + new Point(405.3496076518269, 386.9640073785606), + new Point(410.1838459830034, 369.53596660615716), + new Point(416.2109375, 374.88281250000165), + new Point(416.2109375, 374.88281250000165), + new Point(422.2535426015652, 380.24342104299706), + new Point(414.22090350720225, 470.4670192921159), + new Point(411.89062500000006, 486.89062500000165), + new Point(411.89062500000006, 486.89062500000165), + new Point(411.17903515040365, 491.9058500382896), + new Point(409.62711375255395, 506.8658345044996), + new Point(409.09765625, 501.8281250000016), + new Point(409.09765625, 501.8281250000016), + new Point(406.17489408794324, 474.0184771016202), + new Point(427.5752202763483, 412.64178233372553), + new Point(449.94140625, 393.88671875000165), + new Point(449.94140625, 393.88671875000165), + new Point(460.6024710314065, 384.94693133693863), + new Point(461.7393047003525, 420.1930673831064), + new Point(461.14843750000006, 434.09375000000165), + new Point(461.14843750000006, 434.09375000000165), + new Point(460.1966264683298, 456.4859610664082), + new Point(456.42708333333337, 478.66927083333496), + new Point(454.06640625000006, 500.95703125000165), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(273.69140625, 391.83984374999994), + new Point(276.7200718660503, 297.3353245774439), + new Point(273.61866337177725, 307.87111037764714), + new Point(281.73046875, 240.86328124999994), + new Point(281.73046875, 240.86328124999994), + new Point(282.3920659300252, 235.39813647353918), + new Point(283.00014830949516, 219.1741577727248), + new Point(284.234375, 224.53906249999994), + new Point(284.234375, 224.53906249999994), + new Point(295.66150713184607, 274.21022555697596), + new Point(286.62816859781, 352.56816539019616), + new Point(283.83203125, 403.20312499999994), + new Point(283.83203125, 403.20312499999994), + new Point(283.343734166606, 412.0456459564924), + new Point(282.8299832089477, 385.46396421650365), + new Point(283.54296875, 376.6367187499999), + new Point(283.54296875, 376.6367187499999), + new Point(286.0148120248624, 346.03361940841614), + new Point(289.3089391539035, 315.48701977477253), + new Point(293.375, 285.05468749999994), + new Point(293.375, 285.05468749999994), + new Point(294.1817716411847, 279.0164250185208), + new Point(296.7874044314679, 261.4695464205243), + new Point(298.13671875, 267.41015624999994), + new Point(298.13671875, 267.41015624999994), + new Point(307.5273783401683, 308.75429964225407), + new Point(300.1148726064763, 356.8163792165499), + new Point(295.109375, 398.39843749999994), + new Point(295.109375, 398.39843749999994), + new Point(294.3439686930404, 404.7568801901604), + new Point(291.9803307765164, 423.81508144923663), + new Point(292.47265625, 417.42968749999994), + new Point(292.47265625, 417.42968749999994), + new Point(296.0618286364937, 370.8786133146267), + new Point(299.9163446454934, 308.76363089533254), + new Point(324.34375, 267.01171874999994), + new Point(324.34375, 267.01171874999994), + new Point(326.3536338596459, 263.5763766368116), + new Point(328.4061151034642, 274.17254539154357), + new Point(328.66015625, 278.14453124999994), + new Point(328.66015625, 278.14453124999994), + new Point(330.3077206168786, 303.9045408207935), + new Point(325.95078345906177, 364.1651412283799), + new Point(322.70703125, 386.22265624999994), + new Point(322.70703125, 386.22265624999994), + new Point(322.49054779719006, 387.6947437291075), + new Point(312.1209571101523, 347.4761452211152), + new Point(333.9375, 292.7734374999999), + new Point(333.9375, 292.7734374999999), + new Point(334.68769574152884, 290.89239985853305), + new Point(337.44471100878974, 285.97248464442634), + new Point(337.67578125, 287.98437499999994), + new Point(337.67578125, 287.98437499999994), + new Point(341.1190813993043, 317.9646196452917), + new Point(339.7294155300997, 434.8174594699003), + new Point(332.5625, 441.9843749999999), + new Point(332.5625, 441.9843749999999), + new Point(327.7925860139972, 446.75428898600273), + new Point(332.7012216612796, 428.46032838075814), + new Point(333.58984375, 421.7734374999999), + new Point(333.58984375, 421.7734374999999), + new Point(335.0614474936064, 410.6996033267114), + new Point(341.3463016858058, 365.4599580199776), + new Point(348.84375, 349.4140624999999), + new Point(348.84375, 349.4140624999999), + new Point(351.32348303344276, 344.10698527790964), + new Point(358.11696797993545, 329.9375801469301), + new Point(359.68359375, 335.5820312499999), + new Point(359.68359375, 335.5820312499999), + new Point(367.53042218226017, 363.8536454710824), + new Point(355.7779766743556, 430.6474947101134), + new Point(350.84375, 461.63671875), + new Point(350.84375, 461.63671875), + new Point(349.64302204608, 469.17784525891545), + new Point(344.4752406324922, 491.3601379746957), + new Point(344.7890625, 483.7304687499999), + new Point(344.7890625, 483.7304687499999), + new Point(348.2348630748648, 399.95581400949794), + new Point(359.2900745980749, 316.77363246472447), + new Point(379.6640625, 235.44140624999994), + new Point(379.6640625, 235.44140624999994), + new Point(382.67303912281443, 223.42967989875206), + new Point(385.952156253214, 211.4726490363388), + new Point(389.7890625, 199.69921874999994), + new Point(389.7890625, 199.69921874999994), + new Point(392.026485119306, 192.8337553961475), + new Point(394.96814275767997, 172.98261126521263), + new Point(397.86328125, 179.59765624999994), + new Point(397.86328125, 179.59765624999994), + new Point(409.4632176210204, 206.10212265757372), + new Point(374.80324893726765, 337.50263912574883), + new Point(363.83984375, 374.08593749999994), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(254.08593749999994, 485.60937500000136), + new Point(263.79166666666663, 446.3268229166681), + new Point(268.7306754826251, 405.5488631486394), + new Point(283.20312499999994, 367.7617187500014), + new Point(283.20312499999994, 367.7617187500014), + new Point(284.02344989718654, 365.61987432300424), + new Point(281.44780184228745, 408.4324821921858), + new Point(269.75390624999994, 469.86718750000136), + new Point(269.75390624999994, 469.86718750000136), + new Point(267.391941836259, 482.27593414568094), + new Point(260.3790331456552, 519.4595640418096), + new Point(261.71093749999994, 506.89843750000136), + new Point(261.71093749999994, 506.89843750000136), + new Point(266.9791419372647, 457.2142523190351), + new Point(273.6888160292111, 433.65859082801325), + new Point(287.34374999999994, 388.0156250000014), + new Point(287.34374999999994, 388.0156250000014), + new Point(290.0697995498825, 378.903535061161), + new Point(295.09395179288526, 351.5192670974356), + new Point(296.36328124999994, 360.9453125000014), + new Point(296.36328124999994, 360.9453125000014), + new Point(300.9423229478846, 394.94929365916835), + new Point(263.25910990115545, 462.98578857843523), + new Point(297.55859374999994, 463.8710937500014), + new Point(297.55859374999994, 463.8710937500014), + new Point(333.1840802001626, 464.7906244208676), + new Point(317.4624559157238, 395.3911761117842), + new Point(329.35546874999994, 361.7968750000014), + new Point(329.35546874999994, 361.7968750000014), + new Point(330.14641548599843, 359.56268058830995), + new Point(335.237952013728, 355.31116630870895), + new Point(335.15234374999994, 357.6796875000014), + new Point(335.15234374999994, 357.6796875000014), + new Point(334.01182634055675, 389.2343474786891), + new Point(332.030355399229, 455.6184387699988), + new Point(321.16015624999994, 499.4960937500014), + new Point(321.16015624999994, 499.4960937500014), + new Point(320.3978321774271, 502.57322160939975), + new Point(317.60374259368854, 511.6481282360163), + new Point(318.20312499999994, 508.53515625000136), + new Point(318.20312499999994, 508.53515625000136), + new Point(326.7989582373868, 463.8915568005044), + new Point(334.48527193556686, 410.1330803617849), + new Point(353.54296874999994, 366.7812500000014), + new Point(353.54296874999994, 366.7812500000014), + new Point(354.9156945920997, 363.6586177942631), + new Point(358.49183184927927, 354.71848510200493), + new Point(358.95703124999994, 358.0976562500014), + new Point(358.95703124999994, 358.0976562500014), + new Point(365.1665013820687, 403.2027494253741), + new Point(340.45330746781934, 502.30237197387544), + new Point(324.51171874999994, 547.8828125000014), + new Point(324.51171874999994, 547.8828125000014), + new Point(321.40008829212053, 556.7796351150598), + new Point(314.5954333604323, 582.9299634327003), + new Point(312.89062499999994, 573.6601562500014), + new Point(312.89062499999994, 573.6601562500014), + new Point(306.71142094780964, 540.0610541832864), + new Point(340.22371062343115, 429.14171595873444), + new Point(356.90624999999994, 391.2734375000014), + new Point(356.90624999999994, 391.2734375000014), + new Point(359.21184335636417, 386.0398906603618), + new Point(364.72823604070226, 370.50111209228373), + new Point(365.11328124999994, 376.2070312500014), + new Point(365.11328124999994, 376.2070312500014), + new Point(368.9557899563237, 433.1485111377787), + new Point(358.2323603821659, 495.57929588092236), + new Point(348.29687499999994, 551.2070312500014), + new Point(348.29687499999994, 551.2070312500014), + new Point(346.84171047958495, 559.3543440129408), + new Point(342.56239410948564, 583.4989375821165), + new Point(342.05468749999994, 575.2382812500014), + new Point(342.05468749999994, 575.2382812500014), + new Point(339.1127194424459, 527.3708975889286), + new Point(371.44968935372935, 414.17339535084704), + new Point(395.6562499999999, 375.3867187500014), + new Point(395.6562499999999, 375.3867187500014), + new Point(399.2506237656001, 369.62737875675975), + new Point(407.95491266608724, 354.29800478941956), + new Point(409.87890624999994, 360.8085937500014), + new Point(409.87890624999994, 360.8085937500014), + new Point(413.8287601155713, 374.1744777051883), + new Point(405.66796874999994, 388.3632812500014), + new Point(403.5624999999999, 402.1406250000014), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(335.01953125, 553.6406250000003), + new Point(336.4714776076423, 519.4883215441523), + new Point(337.63072344668353, 484.9218813827357), + new Point(345.84375, 451.56250000000034), + new Point(345.84375, 451.56250000000034), + new Point(347.44061932063914, 445.0763925535219), + new Point(349.55261159061877, 426.27689415148586), + new Point(352, 432.49218750000034), + new Point(352, 432.49218750000034), + new Point(359.4122753554561, 451.3161165247239), + new Point(327.3341233095917, 580.0522401431975), + new Point(329.5546875, 581.8750000000003), + new Point(329.5546875, 581.8750000000003), + new Point(344.3429740824579, 594.0140299140345), + new Point(342.64191335997685, 545.9114395503043), + new Point(349.73046875, 528.1406250000003), + new Point(349.73046875, 528.1406250000003), + new Point(355.2956640664632, 514.1888325030012), + new Point(372.3092460187561, 462.38317203832963), + new Point(389.69921875, 453.61328125000034), + new Point(389.69921875, 453.61328125000034), + new Point(393.24740362609805, 451.82390559420793), + new Point(400.75088749277626, 453.6023094400226), + new Point(390.83203125, 538.2500000000003), + new Point(390.83203125, 538.2500000000003), + new Point(390.25304107952405, 543.1911121189918), + new Point(387.2388348221465, 557.8216283933931), + new Point(388.0546875, 552.9140625000003), + new Point(388.0546875, 552.9140625000003), + new Point(396.32422645461247, 503.1706364754503), + new Point(405.8333201108481, 456.28026776775715), + new Point(423.98828125, 409.12109375000034), + new Point(423.98828125, 409.12109375000034), + new Point(426.6668674336846, 402.16322085841216), + new Point(435.9599425294894, 382.2173917601229), + new Point(434.90234375, 389.59765625000034), + new Point(434.90234375, 389.59765625000034), + new Point(429.84446226890486, 424.8931802359084), + new Point(425.63964874734836, 454.9988541572316), + new Point(414.75390625, 486.87890625000034), + new Point(414.75390625, 486.87890625000034), + new Point(413.8454590916428, 489.5393901571853), + new Point(413.76156407810043, 496.5072047643293), + new Point(411.60546875, 494.70312500000034), + new Point(411.60546875, 494.70312500000034), + new Point(403.7994218844259, 488.1715347655404), + new Point(423.3421500686966, 441.27327868895236), + new Point(426.421875, 433.20312500000034), + new Point(426.421875, 433.20312500000034), + new Point(428.1890601286304, 428.57236871397004), + new Point(428.96703571606804, 416.4183681477017), + new Point(432.671875, 419.71093750000034), + new Point(432.671875, 419.71093750000034), + new Point(456.4378148276652, 440.8322329485025), + new Point(397.08576447590593, 604.6921598277337), + new Point(402.2734375, 622.0898437500003), + new Point(402.2734375, 622.0898437500003), + new Point(404.7932625409085, 630.5404765091445), + new Point(406.4050154360251, 604.9184252376538), + new Point(409.24609375, 596.5703125000003), + new Point(409.24609375, 596.5703125000003), + new Point(420.3114628860083, 564.0562671895393), + new Point(431.7219791395492, 531.6487345391655), + new Point(443.97265625, 499.56250000000034), + new Point(443.97265625, 499.56250000000034), + new Point(445.3294920156815, 496.00875760549656), + new Point(465.1953467654637, 451.8317152807843), + new Point(469.16796875, 449.16796875000034), + new Point(469.16796875, 449.16796875000034), + new Point(472.1561230413946, 447.16433345368137), + new Point(473.36254977826957, 455.56005053773805), + new Point(473.2578125, 459.15625000000034), + new Point(473.2578125, 459.15625000000034), + new Point(472.73073318206747, 477.25374490377146), + new Point(469.9416171657199, 495.23241980725135), + new Point(467.3046875, 513.1445312500003), + new Point(467.3046875, 513.1445312500003), + new Point(460.2199346121074, 561.2697751357236), + new Point(450.82800768703976, 613.4062691691229), + new Point(437.9765625, 660.5507812500003), + new Point(437.9765625, 660.5507812500003), + new Point(437.5611845950558, 662.0745623012956), + new Point(436.3428861490269, 657.590829042756), + new Point(436.56640625, 656.0273437500003), + new Point(436.56640625, 656.0273437500003), + new Point(439.1372058242812, 638.0450356376057), + new Point(441.7343708025927, 619.9911070947221), + new Point(446.2890625, 602.4062500000003), + new Point(446.2890625, 602.4062500000003), + new Point(461.28522589890673, 544.5087219436045), + new Point(473.88059934892783, 491.1447077877355), + new Point(497.0390625, 437.98046875000034), + new Point(497.0390625, 437.98046875000034), + new Point(499.8573603679904, 431.51058080640234), + new Point(505.0796124039013, 411.95862641395075), + new Point(506.25, 418.91796875000034), + new Point(506.25, 418.91796875000034), + new Point(509.4037641434245, 437.67083694034216), + new Point(485.54372047940547, 615.4463133648837), + new Point(474.34765625, 622.9609375000003), + new Point(474.34765625, 622.9609375000003), + new Point(471.4451920488941, 624.9090263185387), + new Point(471.61525823737827, 616.1035220048973), + new Point(472.30078125, 612.6757812500003), + new Point(472.30078125, 612.6757812500003), + new Point(478.77464801663655, 580.3052604225439), + new Point(487.11895349441147, 548.3231346732996), + new Point(495.65234375, 516.4335937500003), + new Point(495.65234375, 516.4335937500003), + new Point(496.95058735737416, 511.58201759963526), + new Point(502.37281172671135, 497.6698202235567), + new Point(501.7421875, 502.65234375000034), + new Point(501.7421875, 502.65234375000034), + new Point(498.3596767162902, 529.3773550077715), + new Point(492.13541666666663, 555.6653645833337), + new Point(487.33203125, 582.1718750000003), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(296.3359375000001, 343.2304687500012), + new Point(296.3359375000001, 317.4272395651978), + new Point(297.4936392446502, 291.20831878938765), + new Point(296.3359375000001, 265.4687500000012), + new Point(296.3359375000001, 265.4687500000012), + new Point(296.02935736297127, 258.65245162006005), + new Point(296.0542483178076, 279.11997821260996), + new Point(295.5156250000001, 285.9218750000012), + new Point(295.5156250000001, 285.9218750000012), + new Point(294.1050372319511, 303.7352003623017), + new Point(291.69025311666053, 321.809035745153), + new Point(288.5937500000001, 339.4375000000012), + new Point(288.5937500000001, 339.4375000000012), + new Point(288.3281390363018, 340.9496293933346), + new Point(287.376144008741, 345.4480643696154), + new Point(287.5429687500001, 343.9218750000012), + new Point(287.5429687500001, 343.9218750000012), + new Point(290.48769681970055, 316.9821498581479), + new Point(307.53197129626074, 257.03210194522785), + new Point(311.3007812500001, 255.94140625000122), + new Point(311.3007812500001, 255.94140625000122), + new Point(323.4793104216741, 252.4169331391833), + new Point(316.16665688049625, 293.6454396992167), + new Point(309.5703125000001, 358.1718750000012), + new Point(309.5703125000001, 358.1718750000012), + new Point(309.03722140586245, 363.3866524602269), + new Point(305.3319556801808, 378.3255272522588), + new Point(308.0117187500001, 373.8203125000012), + new Point(308.0117187500001, 373.8203125000012), + new Point(323.7278480810396, 347.3983729979538), + new Point(328.6799738676958, 311.3824566340299), + new Point(340.7539062500001, 282.7265625000012), + new Point(340.7539062500001, 282.7265625000012), + new Point(343.86345267086125, 275.34646211351566), + new Point(352.2169293229308, 254.21370041072623), + new Point(353.1796875000001, 262.1640625000012), + new Point(353.1796875000001, 262.1640625000012), + new Point(359.1740065354915, 311.664557999154), + new Point(340.5241513366537, 371.18512501724473), + new Point(328.8789062500001, 419.23437500000125), + new Point(328.8789062500001, 419.23437500000125), + new Point(327.61590782742667, 424.44561155899896), + new Point(323.77218440945927, 440.0513314997005), + new Point(324.7187500000001, 434.77343750000125), + new Point(324.7187500000001, 434.77343750000125), + new Point(330.76964013590833, 401.0346696213768), + new Point(339.2530697658525, 326.48041192146695), + new Point(359.4375000000001, 290.1484375000012), + new Point(359.4375000000001, 290.1484375000012), + new Point(361.6633060375085, 286.1419866324861), + new Point(359.72418907179855, 299.3506525625076), + new Point(359.1250000000001, 303.8945312500012), + new Point(359.1250000000001, 303.8945312500012), + new Point(354.4098915389192, 339.65099253061186), + new Point(345.91420893535434, 375.108988206926), + new Point(336.8242187500001, 409.9765625000012), + new Point(336.8242187500001, 409.9765625000012), + new Point(335.2946906839881, 415.843558215898), + new Point(330.00101011158426, 433.1643999319487), + new Point(330.8710937500001, 427.16406250000125), + new Point(330.8710937500001, 427.16406250000125), + new Point(333.50831899476293, 408.9770277668365), + new Point(366.3705229733099, 275.5008134874533), + new Point(374.0273437500001, 275.0585937500012), + new Point(374.0273437500001, 275.0585937500012), + new Point(378.3026922752375, 274.8116709660564), + new Point(376.1794136236944, 283.4703683193167), + new Point(376.0234375000001, 287.7500000000012), + new Point(376.0234375000001, 287.7500000000012), + new Point(375.4856026186785, 302.5069714041114), + new Point(373.6645086842448, 317.1955618569654), + new Point(371.9570312500001, 331.8632812500012), + new Point(371.9570312500001, 331.8632812500012), + new Point(369.57058305670097, 352.3635536069317), + new Point(365.6608061571801, 376.96950271148), + new Point(361.8085937500001, 397.9218750000012), + new Point(361.8085937500001, 397.9218750000012), + new Point(360.5286843944979, 404.88336478235607), + new Point(355.439080363796, 425.5020400555122), + new Point(356.7734375000001, 418.5507812500012), + new Point(356.7734375000001, 418.5507812500012), + new Point(364.23699866946646, 379.6697771379297), + new Point(375.783914748489, 341.391017603424), + new Point(388.6171875000001, 303.9765625000012), + new Point(388.6171875000001, 303.9765625000012), + new Point(392.32908040637426, 293.15481397307957), + new Point(403.3574766796803, 264.6368410866962), + new Point(404.2578125000001, 264.4101562500012), + new Point(404.2578125000001, 264.4101562500012), + new Point(408.8278039863062, 263.25953250451585), + new Point(406.015443641858, 273.790313764377), + new Point(405.5976562500001, 278.4843750000012), + new Point(405.5976562500001, 278.4843750000012), + new Point(402.08489746515335, 317.95206876816786), + new Point(393.8868946701598, 354.24717766185137), + new Point(385.9101562500001, 393.1015625000012), + new Point(385.9101562500001, 393.1015625000012), + new Point(382.0667040260916, 411.8228698751269), + new Point(378.8637582005812, 427.51475920748555), + new Point(374.0507812500001, 445.3984375000012), + new Point(374.0507812500001, 445.3984375000012), + new Point(373.0381813453682, 449.1609759703514), + new Point(372.03735003696937, 460.26667251590146), + new Point(370.7148437500001, 456.6015625000012), + new Point(370.7148437500001, 456.6015625000012), + new Point(361.05637659979175, 429.8346994315493), + new Point(393.93114352507774, 343.0409343456669), + new Point(403.7070312500001, 313.7656250000012), + new Point(403.7070312500001, 313.7656250000012), + new Point(406.654880179691, 304.937865133142), + new Point(413.69038362945787, 279.3386368972901), + new Point(415.5156250000001, 288.4648437500012), + new Point(415.5156250000001, 288.4648437500012), + new Point(423.61445437799705, 328.95899063998576), + new Point(406.1964281484851, 383.2863279465309), + new Point(396.1992187500001, 422.8593750000012), + new Point(396.1992187500001, 422.8593750000012), + new Point(394.192632255341, 430.80226572128953), + new Point(389.38642492769054, 454.3743347812146), + new Point(388.5703125000001, 446.22265625000125), + new Point(388.5703125000001, 446.22265625000125), + new Point(385.8027754438629, 418.5793173675198), + new Point(393.23914631807764, 389.7999286669891), + new Point(402.8671875000001, 364.1914062500012), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(293.91796875000006, 381.2460937499992), + new Point(293.91796875000006, 359.0739558105338), + new Point(305.25072805391846, 266.9328804371235), + new Point(307.58984375000006, 273.7226562499992), + new Point(307.58984375000006, 273.7226562499992), + new Point(321.1641487329526, 313.12493455724325), + new Point(300.46650389564684, 358.29009880393915), + new Point(310.61328125000006, 398.7109374999992), + new Point(310.61328125000006, 398.7109374999992), + new Point(316.19771382519735, 420.95715819136296), + new Point(322.658176495113, 354.2620570865382), + new Point(331.96093750000006, 333.2968749999992), + new Point(331.96093750000006, 333.2968749999992), + new Point(333.50982385450357, 329.8062248116881), + new Point(336.8552929871608, 319.2744396265559), + new Point(337.14843750000006, 323.0820312499992), + new Point(337.14843750000006, 323.0820312499992), + new Point(339.40113419456213, 352.34182868334244), + new Point(337.9793702875343, 373.7978307944368), + new Point(332.98828125000006, 400.0546874999992), + new Point(332.98828125000006, 400.0546874999992), + new Point(332.2114359142652, 404.1414742732625), + new Point(330.35920816582023, 416.3890007484682), + new Point(330.25000000000006, 412.2304687499992), + new Point(330.25000000000006, 412.2304687499992), + new Point(329.52683663294107, 384.69316895699035), + new Point(341.34095494128564, 338.9147960134275), + new Point(346.13671875000006, 318.1328124999992), + new Point(346.13671875000006, 318.1328124999992), + new Point(347.28350293199344, 313.163332993869), + new Point(345.8270074318453, 304.1986274927134), + new Point(350.89062500000006, 303.5898437499992), + new Point(350.89062500000006, 303.5898437499992), + new Point(355.4976793578926, 303.03595124979853), + new Point(353.8949855175869, 312.5862330648649), + new Point(353.70703125000006, 317.2226562499992), + new Point(353.70703125000006, 317.2226562499992), + new Point(353.1388884042395, 331.2375051617694), + new Point(350.69784623048804, 345.1208397377716), + new Point(348.64453125000006, 358.9960937499992), + new Point(348.64453125000006, 358.9960937499992), + new Point(346.68288805251314, 372.2518766693937), + new Point(342.32197044924425, 394.52576592387834), + new Point(338.77734375000006, 409.1015624999992), + new Point(338.77734375000006, 409.1015624999992), + new Point(337.6856206255178, 413.59081779542794), + new Point(339.5852391337851, 421.16542968560657), + new Point(335.15625000000006, 422.4804687499992), + new Point(335.15625000000006, 422.4804687499992), + new Point(331.29300001937577, 423.6275306385194), + new Point(333.7599496746031, 414.40540258254805), + new Point(334.34375000000006, 410.4179687499992), + new Point(334.34375000000006, 410.4179687499992), + new Point(337.30170617887103, 390.2147348192765), + new Point(341.2078985270387, 370.1410482683194), + new Point(345.73437500000006, 350.2304687499992), + new Point(345.73437500000006, 350.2304687499992), + new Point(350.8639382125553, 327.66709592614507), + new Point(360.31596539933713, 290.99986696008324), + new Point(369.82812500000006, 265.8789062499992), + new Point(369.82812500000006, 265.8789062499992), + new Point(372.8165647815901, 257.98664187582455), + new Point(382.4129775409645, 236.13610006210152), + new Point(383.41406250000006, 244.5156249999992), + new Point(383.41406250000006, 244.5156249999992), + new Point(390.39280487766416, 302.9307927247621), + new Point(372.12869176597763, 368.6216911657291), + new Point(355.28125000000006, 424.6093749999992), + new Point(355.28125000000006, 424.6093749999992), + new Point(354.6504146043754, 426.70577712278464), + new Point(354.30163999616104, 420.21706445393204), + new Point(354.71093750000006, 418.0664062499992), + new Point(354.71093750000006, 418.0664062499992), + new Point(358.4319617652032, 398.5142436105224), + new Point(362.69631252749525, 379.0537116933897), + new Point(367.62109375000006, 359.7695312499992), + new Point(367.62109375000006, 359.7695312499992), + new Point(377.6880071445971, 320.3500797782733), + new Point(389.2488872595788, 265.98689160674974), + new Point(410.55468750000006, 228.6093749999992), + new Point(410.55468750000006, 228.6093749999992), + new Point(412.42455168074235, 225.3290063360958), + new Point(418.28437942757324, 216.8699587614023), + new Point(418.59765625000006, 220.6328124999992), + new Point(418.59765625000006, 220.6328124999992), + new Point(424.1191887367268, 286.95345186142725), + new Point(389.84990600209915, 406.09183075293527), + new Point(372.03125000000006, 474.17187499999915), + new Point(372.03125000000006, 474.17187499999915), + new Point(369.6139658642246, 483.40763390919693), + new Point(361.32767769010724, 510.66689809334), + new Point(362.55468750000006, 501.1992187499992), + new Point(362.55468750000006, 501.1992187499992), + new Point(370.1666674380765, 442.4647370526226), + new Point(388.0229589450143, 384.14441052428117), + new Point(407.55859375000006, 328.4101562499992), + new Point(407.55859375000006, 328.4101562499992), + new Point(409.20946933477376, 323.70028526113845), + new Point(427.72529844578435, 275.8971174503191), + new Point(430.09765625, 274.3945312499992), + new Point(430.09765625, 274.3945312499992), + new Point(434.1891158036657, 271.8031132718255), + new Point(433.3512371014903, 283.76305746645943), + new Point(433.140625, 288.6015624999992), + new Point(433.140625, 288.6015624999992), + new Point(432.40763689944697, 305.44089219167506), + new Point(429.989143647208, 322.1898878053871), + new Point(427.29296875, 338.8281249999992), + new Point(427.29296875, 338.8281249999992), + new Point(423.0618017948565, 364.93887897318797), + new Point(399.63689790890487, 478.4389566629949), + new Point(396.45312500000006, 480.2304687499992), + new Point(396.45312500000006, 480.2304687499992), + new Point(392.76411719088156, 482.3062770027186), + new Point(394.5269484566783, 471.80133454471206), + new Point(395.08593750000006, 467.6054687499992), + new Point(395.08593750000006, 467.6054687499992), + new Point(398.0290937487301, 445.5136428366347), + new Point(402.0377432261113, 423.5465095402351), + new Point(406.90234375000006, 401.7968749999992), + new Point(406.90234375000006, 401.7968749999992), + new Point(417.2507935682071, 355.5289439543379), + new Point(429.36499839819976, 287.8710089561877), + new Point(453.8671875, 243.7617187499992), + new Point(453.8671875, 243.7617187499992), + new Point(455.67141193708756, 240.51372082777493), + new Point(460.92434436930387, 232.11832610493383), + new Point(461.6328125, 235.7656249999992), + new Point(461.6328125, 235.7656249999992), + new Point(472.46262325799796, 291.5190951985809), + new Point(439.9385166051958, 400.9206293071335), + new Point(425.49218750000006, 458.8203124999992), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(291.32421875000006, 477.6601562500009), + new Point(291.32421875000006, 438.5792543713379), + new Point(287.7873460043312, 395.70585145584454), + new Point(299.07031250000006, 357.76171875000097), + new Point(299.07031250000006, 357.76171875000097), + new Point(299.67102555893774, 355.74154648101353), + new Point(302.61887741111684, 360.74696254855684), + new Point(302.83203125000006, 362.84375000000097), + new Point(302.83203125000006, 362.84375000000097), + new Point(305.8731375227178, 392.75901450826194), + new Point(302.83203125000006, 424.55398770454946), + new Point(302.83203125000006, 454.7304687500009), + new Point(302.83203125000006, 454.7304687500009), + new Point(302.83203125000006, 456.2669270833343), + new Point(302.5733278257281, 460.85436570373395), + new Point(302.83203125000006, 459.3398437500009), + new Point(302.83203125000006, 459.3398437500009), + new Point(312.1078938038169, 405.0363589117147), + new Point(317.30619819227576, 362.60719449855407), + new Point(325.06250000000006, 364.42968750000097), + new Point(325.06250000000006, 364.42968750000097), + new Point(327.21053812228564, 364.93441056799816), + new Point(328.18457756262836, 395.6527000680093), + new Point(328.26171875000006, 401.46875000000097), + new Point(328.26171875000006, 401.46875000000097), + new Point(328.4998687503365, 419.42403874331507), + new Point(328.2255672771261, 444.77634344326725), + new Point(327.55859375000006, 462.55078125000097), + new Point(327.55859375000006, 462.55078125000097), + new Point(327.5257592471206, 463.4258007306991), + new Point(326.8317634364934, 465.9761971937147), + new Point(326.98046875000006, 465.1132812500009), + new Point(326.98046875000006, 465.1132812500009), + new Point(332.45003918677486, 433.37413606507107), + new Point(342.0690023945331, 384.8257998768927), + new Point(343.64062500000006, 395.56640625000097), + new Point(343.64062500000006, 395.56640625000097), + new Point(345.14823858458965, 405.8695693748509), + new Point(341.7198930262303, 495.4186405494728), + new Point(335.44531250000006, 500.8632812500009), + new Point(335.44531250000006, 500.8632812500009), + new Point(330.7316209726877, 504.9534920030628), + new Point(334.8959611480173, 488.35517444064124), + new Point(335.46875000000006, 482.14062500000097), + new Point(335.46875000000006, 482.14062500000097), + new Point(337.36669388485154, 461.5486283730729), + new Point(345.86374857992996, 398.7743859075917), + new Point(353.66406250000006, 382.41015625000097), + new Point(353.66406250000006, 382.41015625000097), + new Point(356.66124648998243, 376.12238275258704), + new Point(357.766576599775, 395.96141879795704), + new Point(357.63671875000006, 402.92578125000097), + new Point(357.63671875000006, 402.92578125000097), + new Point(357.2478777359796, 423.7795822527963), + new Point(348.10485966726475, 465.3523308428215), + new Point(343.89062500000006, 484.9648437500009), + new Point(343.89062500000006, 484.9648437500009), + new Point(343.19031780786963, 488.2239844787643), + new Point(341.4978358953647, 497.9668650722143), + new Point(341.34765625000006, 494.6367187500009), + new Point(341.34765625000006, 494.6367187500009), + new Point(339.0319138808156, 443.28647807517774), + new Point(359.3122500069873, 384.59014520511096), + new Point(372.95703125000006, 336.62500000000097), + new Point(372.95703125000006, 336.62500000000097), + new Point(375.0887603615934, 329.13138800619237), + new Point(381.8935200166228, 307.81765049246815), + new Point(383.01562500000006, 315.52734375000097), + new Point(383.01562500000006, 315.52734375000097), + new Point(390.6294767955069, 367.8401511265446), + new Point(375.5856528657022, 425.68670890010134), + new Point(369.00781250000006, 477.6796875000009), + new Point(369.00781250000006, 477.6796875000009), + new Point(367.91644053776935, 486.3061782510784), + new Point(363.6133307395251, 512.0240253175568), + new Point(365.40625000000006, 503.5156250000009), + new Point(365.40625000000006, 503.5156250000009), + new Point(375.20193194859735, 457.02965921253735), + new Point(384.37063874566604, 411.2218505030557), + new Point(398.35156250000006, 365.82421875000097), + new Point(398.35156250000006, 365.82421875000097), + new Point(400.47241170660084, 358.9375828612119), + new Point(407.93044840050726, 339.0975377738027), + new Point(407.62500000000006, 346.29687500000097), + new Point(407.62500000000006, 346.29687500000097), + new Point(405.1141621728885, 405.47665203485946), + new Point(400.9347290804984, 437.2120860569479), + new Point(394.21875000000006, 490.72656250000097), + new Point(394.21875000000006, 490.72656250000097), + new Point(392.5801585856038, 503.7832383166551), + new Point(390.9089033161504, 516.8360041292754), + new Point(389.16406250000006, 529.8789062500009), + new Point(389.16406250000006, 529.8789062500009), + new Point(388.81504281620147, 532.487871796804), + new Point(387.8979349043437, 540.3115975606394), + new Point(387.93750000000006, 537.6796875000009), + new Point(387.93750000000006, 537.6796875000009), + new Point(388.36349037054566, 509.3423784811847), + new Point(388.0446231970803, 470.5310027847421), + new Point(400.37890625000006, 443.75000000000097), + new Point(400.37890625000006, 443.75000000000097), + new Point(401.6969543006343, 440.8881677911072), + new Point(401.566736250644, 449.96738080851696), + new Point(401.64453125000006, 453.11718750000097), + new Point(401.64453125000006, 453.11718750000097), + new Point(402.33679554197505, 481.1459646346209), + new Point(400.6918845377227, 497.35194797606755), + new Point(399.00000000000006, 526.3203125000009), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(286.20703125, 461.9531249999985), + new Point(286.20703125, 414.72005208333206), + new Point(286.20703125, 367.4869791666651), + new Point(286.20703125, 320.2539062499985), + new Point(286.20703125, 320.2539062499985), + new Point(286.20703125, 319.7148437499985), + new Point(286.24438712513916, 321.3333271486752), + new Point(286.20703125, 321.8710937499985), + new Point(286.20703125, 321.8710937499985), + new Point(284.40074229322636, 347.8740148346704), + new Point(284.3067783108746, 368.6871411703291), + new Point(279.76953125, 392.7773437499985), + new Point(279.76953125, 392.7773437499985), + new Point(278.79401780280494, 397.95676559915637), + new Point(276.37795206434606, 413.4688189139524), + new Point(276.28125, 408.1992187499985), + new Point(276.28125, 408.1992187499985), + new Point(275.6864357845838, 375.7859180797841), + new Point(287.82242870805044, 298.41636594419754), + new Point(307.578125, 270.8671874999985), + new Point(307.578125, 270.8671874999985), + new Point(309.8899464608863, 267.64336885974956), + new Point(309.6155547955897, 278.61543348031984), + new Point(309.67578125, 282.5820312499985), + new Point(309.67578125, 282.5820312499985), + new Point(310.38583556901244, 329.34719293386866), + new Point(310.4712280185864, 334.70420662039123), + new Point(306.75390625, 368.6406249999985), + new Point(306.75390625, 368.6406249999985), + new Point(306.10751274179825, 374.54172312864887), + new Point(303.4763764546687, 392.15784722149414), + new Point(304.19921875, 386.2656249999985), + new Point(304.19921875, 386.2656249999985), + new Point(307.54244973126146, 359.0134013730549), + new Point(309.4806184075595, 352.0143940470695), + new Point(318.22265625, 320.2382812499985), + new Point(318.22265625, 320.2382812499985), + new Point(319.2215912188853, 316.60728916093024), + new Point(321.79188859622167, 306.02609827499816), + new Point(322.40234375, 309.7421874999985), + new Point(322.40234375, 309.7421874999985), + new Point(330.06530630958827, 356.38976254792175), + new Point(321.66983277919076, 418.9938430314613), + new Point(307.16796875, 464.3632812499985), + new Point(307.16796875, 464.3632812499985), + new Point(305.9987766910984, 468.0211273568966), + new Point(306.6932725191211, 456.63301807784535), + new Point(307.31640625, 452.8437499999985), + new Point(307.31640625, 452.8437499999985), + new Point(311.18707816093325, 429.3062446699142), + new Point(315.6736982929301, 405.86536385956913), + new Point(320.625, 382.5312499999985), + new Point(320.625, 382.5312499999985), + new Point(322.52485230943216, 373.5777721617649), + new Point(332.41295714615796, 340.24868834684526), + new Point(333.390625, 339.8242187499985), + new Point(333.390625, 339.8242187499985), + new Point(337.61359814150387, 337.9907497453417), + new Point(335.59056849711396, 348.8458184238232), + new Point(335.65234375, 353.4492187499985), + new Point(335.65234375, 353.4492187499985), + new Point(335.87271837867036, 369.87120959758295), + new Point(335.6423334626733, 386.33621165036993), + new Point(334.234375, 402.6992187499985), + new Point(334.234375, 402.6992187499985), + new Point(331.21840120562706, 437.7502532215094), + new Point(326.7834689586944, 472.6690037040207), + new Point(322.390625, 507.5742187499985), + new Point(322.390625, 507.5742187499985), + new Point(321.3636187427057, 515.734734944404), + new Point(321.87706119127915, 524.6082667198829), + new Point(317.98046875, 531.8515624999984), + new Point(317.98046875, 531.8515624999984), + new Point(316.25087931280837, 535.0666608354123), + new Point(314.63309078351847, 524.9448153159487), + new Point(315, 521.3124999999985), + new Point(315, 521.3124999999985), + new Point(318.66573891696686, 485.0225432088922), + new Point(332.71971992259927, 376.142420025634), + new Point(355.2421875, 342.9570312499985), + new Point(355.2421875, 342.9570312499985), + new Point(356.1556424803996, 341.6111148423302), + new Point(359.75966720715377, 342.80866847864354), + new Point(359.89453125, 344.4296874999985), + new Point(359.89453125, 344.4296874999985), + new Point(363.520831841437, 388.0165629325654), + new Point(353.50234549853093, 434.1590799924188), + new Point(346.375, 476.9531249999985), + new Point(346.375, 476.9531249999985), + new Point(345.38799633376834, 482.8792975594836), + new Point(344.3622576621095, 488.8011896414672), + new Point(343.16015625, 494.6874999999985), + new Point(343.16015625, 494.6874999999985), + new Point(342.3198761747509, 498.8020857256123), + new Point(343.8602066349056, 509.0906083657405), + new Point(340.25, 506.9453124999985), + new Point(340.25, 506.9453124999985), + new Point(337.3582346480085, 505.22693655044975), + new Point(338.4244212307323, 482.17252635512796), + new Point(348.41796875, 427.5390624999985), + new Point(348.41796875, 427.5390624999985), + new Point(352.98909656770417, 402.54928325251694), + new Point(361.77641914470775, 362.76953185865597), + new Point(370.58203125, 334.9882812499985), + new Point(370.58203125, 334.9882812499985), + new Point(373.02223861826934, 327.2895532542196), + new Point(382.0270476872689, 305.94630580074266), + new Point(382.6796875, 313.9960937499985), + new Point(382.6796875, 313.9960937499985), + new Point(383.8609973492424, 328.566602020058), + new Point(363.8445797330179, 505.9218520653693), + new Point(352.05078125, 504.3046874999985), + new Point(352.05078125, 504.3046874999985), + new Point(346.55563664714913, 503.55119377648657), + new Point(349.7711289435534, 493.32446681564466), + new Point(350.0546875, 487.7851562499985), + new Point(350.0546875, 487.7851562499985), + new Point(351.04209381121177, 468.4961942774786), + new Point(353.1091935146368, 449.2519088972597), + new Point(355.84765625, 430.1328124999985), + new Point(355.84765625, 430.1328124999985), + new Point(360.03228748978836, 400.9170167079508), + new Point(365.6569897110708, 375.3615401903258), + new Point(373.44140625, 347.5624999999985), + new Point(373.44140625, 347.5624999999985), + new Point(375.9112528791581, 338.742395710287), + new Point(384.3406148763805, 313.1922255648697), + new Point(384.37109375, 322.3515624999985), + new Point(384.37109375, 322.3515624999985), + new Point(384.52468548422553, 368.5080728024022), + new Point(373.90055459490554, 416.1037361684521), + new Point(363.515625, 460.8437499999985), + new Point(363.515625, 460.8437499999985), + new Point(360.73826542219706, 472.8090796433537), + new Point(352.970966072502, 503.0119023233517), + new Point(351.92578125, 503.3867187499985), + new Point(351.92578125, 503.3867187499985), + new Point(335.84580688630547, 509.1531998563205), + new Point(394.9205632066659, 275.66815999662373), + new Point(407.35546875, 293.3085937499985), + new Point(407.35546875, 293.3085937499985), + new Point(412.5314062851721, 300.6512939323699), + new Point(398.24250899338733, 467.51797214420344), + new Point(386.18359375, 488.7382812499985), + new Point(386.18359375, 488.7382812499985), + new Point(384.4164993001458, 491.84787192944236), + new Point(384.2882979111157, 481.6810778351365), + new Point(384.6328125, 478.1210937499985), + new Point(384.6328125, 478.1210937499985), + new Point(387.52727765469217, 448.2116204848464), + new Point(394.25751902178604, 420.6410432645574), + new Point(402.6171875, 391.8320312499985), + new Point(402.6171875, 391.8320312499985), + new Point(403.30040833713235, 389.4775219346066), + new Point(405.3352264366737, 382.9167912605449), + new Point(405.96875, 385.2851562499985), + new Point(405.96875, 385.2851562499985), + new Point(407.8076241733711, 392.15960491194966), + new Point(406.3723958333333, 399.5117187499985), + new Point(406.57421875, 406.6249999999985), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(259.91015625, 387.1289062499991), + new Point(259.91015625, 348.56393881538236), + new Point(265.07646516177755, 272.50269324366906), + new Point(271.2109375, 271.2890624999991), + new Point(271.2109375, 271.2890624999991), + new Point(276.7975315747196, 270.1838228073789), + new Point(274.88791156775756, 357.4688768240901), + new Point(274.32421875, 365.3203124999991), + new Point(274.32421875, 365.3203124999991), + new Point(273.8239468709542, 372.2883851009936), + new Point(274.14813798979367, 351.32480259692835), + new Point(274.77734375, 344.3671874999991), + new Point(274.77734375, 344.3671874999991), + new Point(274.8512994512202, 343.5494020697688), + new Point(281.6527741870951, 277.6615790531602), + new Point(291.37890625, 277.9648437499991), + new Point(291.37890625, 277.9648437499991), + new Point(297.06014124521244, 278.1419869347051), + new Point(293.90234375, 316.80769855180716), + new Point(293.90234375, 327.9140624999991), + new Point(293.90234375, 327.9140624999991), + new Point(293.90234375, 329.9179687499991), + new Point(293.90234375, 335.9296874999991), + new Point(293.90234375, 333.9257812499991), + new Point(293.90234375, 333.9257812499991), + new Point(293.90234375, 327.678756885941), + new Point(300.85434465610194, 264.1102515231514), + new Point(310.1796875, 280.0937499999991), + new Point(310.1796875, 280.0937499999991), + new Point(321.73279707132986, 299.8956074037764), + new Point(313.949728184569, 325.8035988110284), + new Point(314.8671875, 348.7109374999991), + new Point(314.8671875, 348.7109374999991), + new Point(314.97789209657117, 351.4750357498389), + new Point(314.5681865956141, 354.41739697243077), + new Point(313.25390625, 356.8515624999991), + new Point(313.25390625, 356.8515624999991), + new Point(312.6630316739693, 357.94591541251907), + new Point(312.4032512591133, 354.4541462859591), + new Point(312.4375, 353.2109374999991), + new Point(312.4375, 353.2109374999991), + new Point(312.9614925146813, 334.19032298503953), + new Point(314.0002588858493, 302.8609206386323), + new Point(326.91015625, 286.9609374999991), + new Point(326.91015625, 286.9609374999991), + new Point(332.18159195523873, 280.46857458916514), + new Point(330.8743525177327, 303.3457885716256), + new Point(331.04296875, 311.7070312499991), + new Point(331.04296875, 311.7070312499991), + new Point(331.4185412917504, 330.33070183427805), + new Point(336.28907195585117, 368.5983468388478), + new Point(326.86328125, 387.0664062499991), + new Point(326.86328125, 387.0664062499991), + new Point(321.5804184612184, 397.4171796640124), + new Point(329.11793401608753, 336.17554136924736), + new Point(333.76171875, 321.1562499999991), + new Point(333.76171875, 321.1562499999991), + new Point(335.6284303409856, 315.1187855407575), + new Point(337.2453914791018, 299.3886905577757), + new Point(341.65234375, 303.9179687499991), + new Point(341.65234375, 303.9179687499991), + new Point(351.9431071502546, 314.4943778837889), + new Point(344.609375, 358.9130304968471), + new Point(344.609375, 373.4062499999991), + new Point(344.609375, 373.4062499999991), + new Point(344.609375, 377.17597037342114), + new Point(344.65241003277583, 388.48132180164527), + new Point(344.49609375, 384.7148437499991), + new Point(344.49609375, 384.7148437499991), + new Point(344.1861210157591, 377.2459769154328), + new Point(345.5149924458775, 322.04896331685455), + new Point(358.73828125, 320.6562499999991), + new Point(358.73828125, 320.6562499999991), + new Point(362.58438430746753, 320.25116779802346), + new Point(361.21191767494815, 363.9617410666532), + new Point(359.37890625, 398.8867187499991), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(276.9609375, 432.62890624999756), + new Point(276.9609375, 385.5831186855529), + new Point(276.9609375, 368.34314606107193), + new Point(276.9609375, 374.12499999999756), + new Point(276.9609375, 374.12499999999756), + new Point(276.9609375, 387.73177083333087), + new Point(276.9609375, 401.33854166666424), + new Point(276.9609375, 414.94531249999756), + new Point(276.9609375, 414.94531249999756), + new Point(276.9609375, 417.94531249999756), + new Point(275.6976035806361, 426.66633940324283), + new Point(276.9609375, 423.94531249999756), + new Point(276.9609375, 423.94531249999756), + new Point(287.3206569642119, 401.6320705770797), + new Point(289.67698254679004, 366.1463082522259), + new Point(297.75, 342.58203124999756), + new Point(297.75, 342.58203124999756), + new Point(298.9056219981234, 339.2088938783173), + new Point(299.9832317114675, 330.031945516778), + new Point(302.17578125, 332.84374999999756), + new Point(302.17578125, 332.84374999999756), + new Point(321.2026016073923, 357.24442959337), + new Point(314.77572045986244, 385.94921592178156), + new Point(320.78125, 413.91015624999756), + new Point(320.78125, 413.91015624999756), + new Point(322.9543617085228, 424.0278729979469), + new Point(326.2092687257936, 373.01132048973494), + new Point(326.30078125, 383.35937499999756), + new Point(326.30078125, 383.35937499999756), + new Point(326.52726151847014, 408.96931401055167), + new Point(323.41404597715905, 434.5135638930957), + new Point(322.99609375, 460.1210937499975), + new Point(322.99609375, 460.1210937499975), + new Point(322.8344153387938, 470.02697407110907), + new Point(324.23268997067316, 440.3295407947057), + new Point(325.53125, 430.50781249999756), + new Point(325.53125, 430.50781249999756), + new Point(328.6337911661713, 407.04157630829997), + new Point(333.1221178884131, 382.7413072446474), + new Point(341.8125, 360.52734374999756), + new Point(341.8125, 360.52734374999756), + new Point(342.67419600632434, 358.32471521396883), + new Point(344.11757952346096, 352.09319532897143), + new Point(345.10546875, 354.24218749999756), + new Point(345.10546875, 354.24218749999756), + new Point(353.90815660310693, 373.3910017315153), + new Point(343.9491937156452, 438.4754014003165), + new Point(338.8359375, 461.63671874999756), + new Point(338.8359375, 461.63671874999756), + new Point(334.97392985110326, 479.1303042443644), + new Point(341.8373603196162, 425.8343638698472), + new Point(345.60546875, 408.32031249999756), + new Point(345.60546875, 408.32031249999756), + new Point(347.06442995515926, 401.53910597002135), + new Point(354.83924946692974, 355.5431651010594), + new Point(363.79296875, 349.14843749999756), + new Point(363.79296875, 349.14843749999756), + new Point(366.9826937801836, 346.8703425491227), + new Point(358.0245823399134, 465.5775928425928), + new Point(352.87890625, 463.5859374999975), + new Point(352.87890625, 463.5859374999975), + new Point(342.836222735195, 459.6988750563544), + new Point(362.9645558352352, 383.20947380379886), + new Point(370.15625, 373.18749999999756), + new Point(370.15625, 373.18749999999756), + new Point(374.57552424961705, 367.0290274973054), + new Point(373.2956595963976, 388.17095919079816), + new Point(373.0234375, 395.74609374999756), + new Point(373.0234375, 395.74609374999756), + new Point(372.5291036872134, 409.5019394310579), + new Point(374.0933945673556, 462.20848763360965), + new Point(362.07421875, 474.89843749999756), + new Point(362.07421875, 474.89843749999756), + new Point(356.8771463355166, 480.38555154125737), + new Point(374.6331425576622, 350.1584214111888), + new Point(384.3671875, 362.33984374999756), + new Point(384.3671875, 362.33984374999756), + new Point(392.02177957632506, 371.9189878227206), + new Point(379.5151653760302, 451.5401620309561), + new Point(376.53125, 467.60546874999756), + new Point(376.53125, 467.60546874999756), + new Point(375.27349128521143, 474.377202189204), + new Point(375.11948950189065, 493.3774317382439), + new Point(371.35546875, 487.6093749999975), + new Point(371.35546875, 487.6093749999975), + new Point(359.13957557723063, 468.88950877888345), + new Point(376.9381064482935, 414.5310274187473), + new Point(384.98046875, 395.47265624999756), + new Point(384.98046875, 395.47265624999756), + new Point(386.9330472775304, 390.8455373864381), + new Point(388.7189598263666, 378.1848405585608), + new Point(391.88671875, 382.08203124999756), + new Point(391.88671875, 382.08203124999756), + new Point(400.48531019761907, 392.660598419084), + new Point(395.6624334934982, 440.9254479188357), + new Point(395.34765625, 448.3945312499975), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(301.35156250000006, 476.83984375000045), + new Point(309.99218750000006, 405.76953125000045), + new Point(312.96559641495594, 333.77828545412035), + new Point(327.27343750000006, 263.62890625000045), + new Point(327.27343750000006, 263.62890625000045), + new Point(330.85276634854694, 246.07994863993721), + new Point(333.43129450320646, 299.03909261720196), + new Point(333.96484375000006, 316.94140625000045), + new Point(333.96484375000006, 316.94140625000045), + new Point(334.75563958923397, 343.4751802522247), + new Point(332.3748887703651, 370.0102064835762), + new Point(331.23437500000006, 396.53125000000045), + new Point(331.23437500000006, 396.53125000000045), + new Point(331.10623324973767, 399.51100616190297), + new Point(329.7572742383297, 408.3692364673378), + new Point(330.16015625000006, 405.41406250000045), + new Point(330.16015625000006, 405.41406250000045), + new Point(331.92253292347175, 392.4868790685696), + new Point(341.30351948335243, 327.8390800226756), + new Point(353.77734375000006, 319.30859375000045), + new Point(353.77734375000006, 319.30859375000045), + new Point(355.73186794624104, 317.97195139644214), + new Point(356.9525648667934, 323.2546710746448), + new Point(357.03515625000006, 325.62109375000045), + new Point(357.03515625000006, 325.62109375000045), + new Point(357.9793751776025, 352.6750186756525), + new Point(357.6573489999199, 379.77421807380813), + new Point(356.83203125000006, 406.83203125000045), + new Point(356.83203125000006, 406.83203125000045), + new Point(356.34397877601117, 422.83269603959457), + new Point(354.53162496116556, 438.76718628951915), + new Point(353.09765625000006, 454.71093750000045), + new Point(353.09765625000006, 454.71093750000045), + new Point(352.7966683516895, 458.0575071501347), + new Point(353.8580009175301, 462.1693823226701), + new Point(351.62890625000006, 464.68359375000045), + new Point(351.62890625000006, 464.68359375000045), + new Point(349.92204819853447, 466.6087708545605), + new Point(350.85167560982075, 459.5469142818091), + new Point(351.08203125000006, 456.9843750000004), + new Point(351.08203125000006, 456.9843750000004), + new Point(352.7526641186911, 438.3997970484062), + new Point(356.73997670216613, 414.4340556992246), + new Point(361.42578125000006, 396.45703125000045), + new Point(361.42578125000006, 396.45703125000045), + new Point(364.77332594775845, 383.61422223776975), + new Point(368.136061215683, 370.7130129677155), + new Point(372.95703125000006, 358.34765625000045), + new Point(372.95703125000006, 358.34765625000045), + new Point(373.47639860852433, 357.01552545267646), + new Point(376.7952179654459, 355.2867630339053), + new Point(376.92187500000006, 356.71093750000045), + new Point(376.92187500000006, 356.71093750000045), + new Point(379.6299381193468, 387.1613136731353), + new Point(382.2885269519142, 433.78403558723073), + new Point(377.05078125000006, 466.91796875000045), + new Point(377.05078125000006, 466.91796875000045), + new Point(376.7676001311144, 468.709370013083), + new Point(374.75472070060505, 473.67292392762477), + new Point(374.77343750000006, 471.85937500000045), + new Point(374.77343750000006, 471.85937500000045), + new Point(375.0367210114321, 446.3487350801323), + new Point(376.0928252376527, 420.8383589777012), + new Point(377.78906250000006, 395.38281250000045), + new Point(377.78906250000006, 395.38281250000045), + new Point(377.8188061631205, 394.93644735062765), + new Point(383.0672446741826, 353.94428515604284), + new Point(387.76953125000006, 352.84375000000045), + new Point(387.76953125000006, 352.84375000000045), + new Point(393.5043432662542, 351.5015599536431), + new Point(389.2470930568602, 364.54468620333336), + new Point(389.48437500000006, 370.42968750000045), + new Point(389.48437500000006, 370.42968750000045), + new Point(390.0028611635207, 383.28903829697435), + new Point(389.93489730644194, 396.1657476013626), + new Point(390.03515625000006, 409.03515625000045), + new Point(390.03515625000006, 409.03515625000045), + new Point(390.27910060359756, 440.3482687022099), + new Point(390.3764209256217, 444.25180514852093), + new Point(388.02343750000006, 476.3750000000004), + new Point(388.02343750000006, 476.3750000000004), + new Point(387.9570619718278, 477.28116618954084), + new Point(387.28289234334073, 479.9005346543151), + new Point(387.26171875000006, 478.99218750000045), + new Point(387.26171875000006, 478.99218750000045), + new Point(386.3529306399379, 440.0051775783319), + new Point(389.1710904298156, 399.1416429740235), + new Point(402.23828125000006, 362.11718750000045), + new Point(402.23828125000006, 362.11718750000045), + new Point(403.8319207160537, 357.601784437132), + new Point(405.28590292033414, 344.793892408018), + new Point(407.79687500000006, 348.87109375000045), + new Point(407.79687500000006, 348.87109375000045), + new Point(418.4941456808508, 366.24083144191343), + new Point(411.5429928213054, 413.71703315128946), + new Point(410.21875000000006, 432.44140625000045), + new Point(410.21875000000006, 432.44140625000045), + new Point(410.12292226415315, 433.7963800133723), + new Point(409.31181514542067, 437.7351054150673), + new Point(409.18359375000006, 436.38281250000045), + new Point(409.18359375000006, 436.38281250000045), + new Point(404.7007708148806, 389.10451175483706), + new Point(426.8272790578519, 308.82971483253056), + new Point(440.15625, 323.88281250000045), + new Point(440.15625, 323.88281250000045), + new Point(449.0208721676156, 333.8940897286407), + new Point(442.6940215525018, 377.3642189219066), + new Point(442.203125, 390.75390625000045), + new Point(442.203125, 390.75390625000045), + new Point(442.06659258393654, 394.47796247309526), + new Point(442.66525730242404, 405.3498437742147), + new Point(441.26953125000006, 401.89453125000045), + new Point(441.26953125000006, 401.89453125000045), + new Point(433.5628813831314, 382.8156555935066), + new Point(444.0880849475494, 314.3268401891793), + new Point(462.69921875, 300.16015625000045), + new Point(462.69921875, 300.16015625000045), + new Point(477.9745400768712, 288.5326728519343), + new Point(470.2918805263468, 373.6617718688937), + new Point(470.83984375, 382.02734375000045), + new Point(470.83984375, 382.02734375000045), + new Point(471.35877843776643, 389.9497466499005), + new Point(474.74641825085826, 366.61172323842607), + new Point(477.421875, 359.13671875000045), + new Point(477.421875, 359.13671875000045), + new Point(478.99839267453825, 354.732058986005), + new Point(487.0393125357273, 347.01696081365714), + new Point(489.03125000000006, 351.25000000000045), + new Point(489.03125000000006, 351.25000000000045), + new Point(500.9292849621029, 376.5343521136606), + new Point(495.51171875, 413.8703804955044), + new Point(495.51171875, 441.70703125000045), + new Point(495.51171875, 441.70703125000045), + new Point(495.51171875, 443.2096354166671), + new Point(495.4010649860903, 438.69774303282554), + new Point(495.51171875, 437.19921875000045), + new Point(495.51171875, 437.19921875000045), + new Point(496.9143200579124, 418.2045452317557), + new Point(495.14967837537085, 352.85340769618557), + new Point(518.984375, 335.00781250000045), + new Point(518.984375, 335.00781250000045), + new Point(522.1509163113883, 332.63694890962273), + new Point(522.9078678093599, 342.00090726315176), + new Point(523.796875, 345.85546875000045), + new Point(523.796875, 345.85546875000045), + new Point(529.1864963529114, 369.22381392690613), + new Point(529.2098686638187, 398.0388677192801), + new Point(530.41015625, 420.93359375000045), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(203.28124999999991, 442.7773437499987), + new Point(203.28124999999991, 413.61718749999864), + new Point(202.9812739112316, 384.4554882535569), + new Point(203.28124999999991, 355.2968749999987), + new Point(203.28124999999991, 355.2968749999987), + new Point(203.30344831433337, 353.1391294770546), + new Point(203.49433933013563, 346.6705810005877), + new Point(203.53124999999991, 348.8281249999987), + new Point(203.53124999999991, 348.8281249999987), + new Point(203.83010028903064, 366.296858300998), + new Point(203.53124999999991, 383.8007465539321), + new Point(203.53124999999991, 401.27343749999864), + new Point(203.53124999999991, 401.27343749999864), + new Point(203.53124999999991, 403.833333333332), + new Point(202.63472367350747, 411.3508963034018), + new Point(203.53124999999991, 408.9531249999987), + new Point(203.53124999999991, 408.9531249999987), + new Point(212.04539739723734, 386.18192721274437), + new Point(215.55594414691146, 361.81190218275657), + new Point(222.9609374999999, 338.6562499999987), + new Point(222.9609374999999, 338.6562499999987), + new Point(225.31113890072237, 331.30709469361847), + new Point(227.8614358943535, 312.27393689929346), + new Point(233.1640624999999, 317.8789062499987), + new Point(233.1640624999999, 317.8789062499987), + new Point(241.73669576243333, 326.9403300054656), + new Point(234.96884956384815, 342.8051279976836), + new Point(234.5937499999999, 355.2734374999987), + new Point(234.5937499999999, 355.2734374999987), + new Point(231.77900285719824, 448.8356325267262), + new Point(224.60412366508695, 353.4552149769061), + new Point(243.9960937499999, 336.9374999999987), + new Point(243.9960937499999, 336.9374999999987), + new Point(245.40101057500488, 335.74081830236406), + new Point(246.0626112594121, 405.2866622832893), + new Point(243.3281249999999, 421.0976562499987), + new Point(243.3281249999999, 421.0976562499987), + new Point(243.11150411425274, 422.3501736125646), + new Point(242.39161374764097, 426.0716194637464), + new Point(242.41796874999991, 424.80078124999864), + new Point(242.41796874999991, 424.80078124999864), + new Point(242.86348197834405, 403.3181333792428), + new Point(251.30786217941437, 377.3066704316581), + new Point(256.1874999999999, 359.4960937499987), + new Point(256.1874999999999, 359.4960937499987), + new Point(257.7343125374707, 353.8502601197743), + new Point(261.1475397361298, 337.30935864457797), + new Point(262.3281249999999, 343.0429687499987), + new Point(262.3281249999999, 343.0429687499987), + new Point(267.3532043132917, 367.44768259233655), + new Point(266.40635017682536, 392.7104169036031), + new Point(268.1445312499999, 417.56640624999864), + new Point(268.1445312499999, 417.56640624999864), + new Point(268.2433458977106, 418.9794557122619), + new Point(267.32574107453473, 423.12611578970916), + new Point(267.8359374999999, 421.80468749999864), + new Point(267.8359374999999, 421.80468749999864), + new Point(279.0513720741798, 392.75628224273567), + new Point(284.50493849972725, 360.7157002073905), + new Point(302.8359374999999, 334.8476562499987), + new Point(302.8359374999999, 334.8476562499987), + new Point(304.9914618132396, 331.8058581633105), + new Point(309.28235518581926, 323.0843765768207), + new Point(310.4257812499999, 326.6328124999987), + new Point(310.4257812499999, 326.6328124999987), + new Point(318.3325056767353, 351.1700395839396), + new Point(314.07491055066527, 392.964382116271), + new Point(311.5429687499999, 417.66796874999864), + new Point(311.5429687499999, 417.66796874999864), + new Point(311.16501947895443, 421.35553477460957), + new Point(309.0536550807218, 432.2295575869455), + new Point(309.1289062499999, 428.52343749999864), + new Point(309.1289062499999, 428.52343749999864), + new Point(310.01507575226333, 384.8795895135236), + new Point(317.1199741979986, 341.1536722289939), + new Point(329.1054687499999, 299.2109374999987), + new Point(329.1054687499999, 299.2109374999987), + new Point(331.4265446243662, 291.08842997542087), + new Point(341.5912652015719, 269.8552470953663), + new Point(343.1992187499999, 278.1484374999987), + new Point(343.1992187499999, 278.1484374999987), + new Point(349.5074220220222, 310.6836627228616), + new Point(341.5107653825801, 352.19392591575087), + new Point(335.4999999999999, 384.0156249999987), + new Point(335.4999999999999, 384.0156249999987), + new Point(335.16001343512175, 385.8155538728831), + new Point(333.8247219139413, 391.14153599780616), + new Point(334.1093749999999, 389.3320312499987), + new Point(334.1093749999999, 389.3320312499987), + new Point(342.32387196292393, 337.1134817830838), + new Point(340.999960999386, 336.9841253063294), + new Point(358.6132812499999, 287.0976562499987), + new Point(358.6132812499999, 287.0976562499987), + new Point(360.0415652864384, 283.052306118756), + new Point(362.9100265384477, 271.75167937605147), + new Point(364.5898437499999, 275.6992187499987), + new Point(364.5898437499999, 275.6992187499987), + new Point(376.39098906837074, 303.43169195099455), + new Point(370.8253788136082, 376.16108069983017), + new Point(362.4179687499999, 407.9492187499987), + new Point(362.4179687499999, 407.9492187499987), + new Point(360.21473625274604, 416.2795676029086), + new Point(362.5641893834993, 390.59958252046016), + new Point(364.3593749999999, 382.1718749999987), + new Point(364.3593749999999, 382.1718749999987), + new Point(369.75683074118126, 356.832891708687), + new Point(376.1130670573121, 331.69129141182367), + new Point(383.0664062499999, 306.7343749999987), + new Point(383.0664062499999, 306.7343749999987), + new Point(384.95069270658007, 299.97129638558886), + new Point(386.17387355836325, 292.40899544547625), + new Point(390.8320312499999, 287.1562499999987), + new Point(390.8320312499999, 287.1562499999987), + new Point(392.76300535703194, 284.9787978574363), + new Point(399.2567233334216, 285.3029913308937), + new Point(399.4999999999999, 288.2031249999987), + new Point(399.4999999999999, 288.2031249999987), + new Point(401.391449925238, 310.75135245132805), + new Point(402.6865492745245, 386.0605522946328), + new Point(388.0195312499999, 415.9101562499987), + new Point(388.0195312499999, 415.9101562499987), + new Point(387.5249078585284, 416.9167897945812), + new Point(386.9527060000336, 413.80966648240576), + new Point(387.0390624999999, 412.69140624999864), + new Point(387.0390624999999, 412.69140624999864), + new Point(387.756201180801, 403.40492905171675), + new Point(388.8137428684968, 394.1294211458883), + new Point(390.4101562499999, 384.9531249999987), + new Point(390.4101562499999, 384.9531249999987), + new Point(390.72440839468857, 383.14678161954623), + new Point(407.59553702228186, 295.87545025196357), + new Point(421.8203124999999, 300.9960937499987), + new Point(421.8203124999999, 300.9960937499987), + new Point(427.6234870913997, 303.08512413827873), + new Point(416.76558011380155, 384.4775000030277), + new Point(402.0156249999999, 445.37499999999864), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(267.74609374999994, 511.9374999999993), + new Point(267.74609374999994, 475.5636006973508), + new Point(267.00683884230904, 466.595210458604), + new Point(285.38671874999994, 412.8515624999993), + new Point(285.38671874999994, 412.8515624999993), + new Point(290.000846413267, 399.3596325191662), + new Point(281.6569080144894, 469.3915680774911), + new Point(285.38671874999994, 455.6289062499993), + new Point(285.38671874999994, 455.6289062499993), + new Point(294.9580665796652, 420.3115047103339), + new Point(301.9801628464335, 386.0998124766359), + new Point(316.20703124999994, 352.2343749999993), + new Point(316.20703124999994, 352.2343749999993), + new Point(318.26893282796203, 347.3262534801609), + new Point(323.32038708911733, 332.51257931686285), + new Point(323.10937499999994, 337.8320312499993), + new Point(323.10937499999994, 337.8320312499993), + new Point(321.2769960522201, 384.0248905159083), + new Point(315.6635729715407, 429.99313257951343), + new Point(311.29687499999994, 476.0156249999993), + new Point(311.29687499999994, 476.0156249999993), + new Point(310.37279854679787, 485.7548608804317), + new Point(310.43598153199866, 456.3849603668063), + new Point(311.57031249999994, 446.6679687499993), + new Point(311.57031249999994, 446.6679687499993), + new Point(314.1656038152041, 424.43598825717464), + new Point(317.43705926401344, 374.7986156778172), + new Point(332.16796874999994, 353.5195312499993), + new Point(332.16796874999994, 353.5195312499993), + new Point(333.45294539865984, 351.6633575615641), + new Point(338.2198171474276, 349.40456329097685), + new Point(338.66796874999994, 351.6171874999993), + new Point(338.66796874999994, 351.6171874999993), + new Point(343.87344284910085, 377.31777173309996), + new Point(337.30932570131046, 411.11406036466735), + new Point(333.67187499999994, 436.9648437499993), + new Point(333.67187499999994, 436.9648437499993), + new Point(332.87797006921676, 442.60699977614934), + new Point(329.0271924876485, 459.1891527357495), + new Point(329.33984374999994, 453.4999999999993), + new Point(329.33984374999994, 453.4999999999993), + new Point(330.61975700093467, 430.2100829265388), + new Point(337.85179529963796, 404.99858733419927), + new Point(343.77734374999994, 383.2382812499993), + new Point(343.77734374999994, 383.2382812499993), + new Point(345.10826317214054, 378.3507650577358), + new Point(350.29188289922064, 364.80245749023027), + new Point(350.92578124999994, 369.8281249999993), + new Point(350.92578124999994, 369.8281249999993), + new Point(355.5683093048086, 406.63497641325637), + new Point(347.5429932064571, 448.0149162956959), + new Point(342.57421874999994, 484.0898437499993), + new Point(342.57421874999994, 484.0898437499993), + new Point(341.71612227988516, 490.3199047397783), + new Point(338.52325983328, 508.8045021323701), + new Point(338.51953124999994, 502.5156249999993), + new Point(338.51953124999994, 502.5156249999993), + new Point(338.50729022668315, 481.869099005678), + new Point(361.23108730185714, 347.02220452330795), + new Point(377.20312499999994, 352.2031249999993), + new Point(377.20312499999994, 352.2031249999993), + new Point(385.2775695357922, 354.8222682692554), + new Point(378.1215487026036, 369.168398086665), + new Point(378.00781249999994, 377.6562499999993), + new Point(378.00781249999994, 377.6562499999993), + new Point(377.7997560374625, 393.18298997551557), + new Point(377.18771136116396, 408.70794985067397), + new Point(376.23828124999994, 424.2070312499993), + new Point(376.23828124999994, 424.2070312499993), + new Point(374.69592463403006, 449.38540979162445), + new Point(371.92813489488765, 475.1485387257949), + new Point(366.55078124999994, 499.8789062499993), + new Point(366.55078124999994, 499.8789062499993), + new Point(366.22804409334077, 501.3631695186958), + new Point(365.01904287136836, 505.6868970170141), + new Point(365.01171874999994, 504.1679687499993), + new Point(365.01171874999994, 504.1679687499993), + new Point(364.7589056984637, 451.73780396527013), + new Point(378.52504990064847, 401.690345629638), + new Point(394.24218749999994, 352.1562499999993), + new Point(394.24218749999994, 352.1562499999993), + new Point(396.5703527645174, 344.81880957070825), + new Point(405.39728125276883, 324.27500590322023), + new Point(405.4648437499999, 331.9726562499993), + new Point(405.4648437499999, 331.9726562499993), + new Point(405.53415840030414, 339.8699360104846), + new Point(398.0508036328354, 494.54920684172475), + new Point(386.7890624999999, 494.0703124999993), + new Point(386.7890624999999, 494.0703124999993), + new Point(384.6667252101755, 493.9800622174416), + new Point(394.46643595958636, 377.52825055288696), + new Point(409.46874999999994, 377.9453124999993), + new Point(409.46874999999994, 377.9453124999993), + new Point(417.66462942673957, 378.1731566460961), + new Point(419.2293364517062, 417.3863424223666), + new Point(418.7773437499999, 448.3437499999993), + new Point(418.7773437499999, 448.3437499999993), + new Point(418.3978136782514, 474.33812352579594), + new Point(417.2980661049294, 500.32122523493854), + new Point(415.9843749999999, 526.2851562499993), + new Point(415.9843749999999, 526.2851562499993), + new Point(415.5683198438609, 534.5081147003683), + new Point(410.7608752109028, 558.7707305853081), + new Point(411.45312499999994, 550.5664062499993), + new Point(411.45312499999994, 550.5664062499993), + new Point(414.6881824912308, 512.2255337507173), + new Point(416.4964889950098, 477.1535929245201), + new Point(435.19140624999994, 443.7734374999993), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(262.21484375000006, 427.2695312500024), + new Point(262.21484375000006, 393.6399030977807), + new Point(263.2383711550731, 336.16435794587534), + new Point(263.59375000000006, 338.2070312500024), + new Point(263.59375000000006, 338.2070312500024), + new Point(267.6803898521325, 361.6965277371888), + new Point(262.7909401474271, 391.6130211209393), + new Point(260.28125000000006, 414.9726562500024), + new Point(260.28125000000006, 414.9726562500024), + new Point(260.10012391949556, 416.6585373366695), + new Point(259.0893731359012, 421.6485564875008), + new Point(259.43359375000006, 419.9882812500024), + new Point(259.43359375000006, 419.9882812500024), + new Point(268.6920329928736, 375.33216019499446), + new Point(278.98342749915645, 331.5166882240446), + new Point(296.51953125000006, 289.2500000000024), + new Point(296.51953125000006, 289.2500000000024), + new Point(297.64246685252516, 286.5434256273843), + new Point(300.4810018838083, 278.4267079382237), + new Point(300.38671875000006, 281.3554687500024), + new Point(300.38671875000006, 281.3554687500024), + new Point(299.00394528194954, 324.30920375239543), + new Point(295.17011235681827, 372.8511464389658), + new Point(285.02343750000006, 415.7695312500024), + new Point(285.02343750000006, 415.7695312500024), + new Point(284.75550587796596, 416.9028278836063), + new Point(284.98792978475774, 413.4131580986474), + new Point(285.27734375000006, 412.2851562500024), + new Point(285.27734375000006, 412.2851562500024), + new Point(292.75560295540095, 383.138358854528), + new Point(296.83373167014054, 364.14552482779544), + new Point(306.68750000000006, 338.7109375000024), + new Point(306.68750000000006, 338.7109375000024), + new Point(309.0498462900835, 332.61323954301463), + new Point(315.3290977155407, 315.5585398498713), + new Point(316.83593750000006, 321.9218750000024), + new Point(316.83593750000006, 321.9218750000024), + new Point(324.43491027571383, 354.0120886161348), + new Point(314.6003351037553, 393.9851138432229), + new Point(309.82812500000006, 426.1718750000024), + new Point(309.82812500000006, 426.1718750000024), + new Point(309.24910395255097, 430.07715405389945), + new Point(307.6169764199992, 441.7985351590328), + new Point(307.93359375000006, 437.8632812500024), + new Point(307.93359375000006, 437.8632812500024), + new Point(311.10249416926325, 398.4768466470654), + new Point(319.5655800057207, 357.1971010338244), + new Point(335.06250000000006, 320.6640625000024), + new Point(335.06250000000006, 320.6640625000024), + new Point(336.59052443969574, 317.06183858992017), + new Point(340.0657734144434, 306.3449801965529), + new Point(340.45703125000006, 310.2382812500024), + new Point(340.45703125000006, 310.2382812500024), + new Point(344.54755028047225, 350.9419313835151), + new Point(336.07705577012126, 393.09061515565514), + new Point(327.44140625000006, 432.6601562500024), + new Point(327.44140625000006, 432.6601562500024), + new Point(325.8326125950073, 440.0318341411946), + new Point(321.88115554145736, 461.99720253721534), + new Point(321.37890625000006, 454.4687500000024), + new Point(321.37890625000006, 454.4687500000024), + new Point(318.0971980884678, 405.27767187345563), + new Point(335.9019292767637, 349.18587245267605), + new Point(352.30078125000006, 303.2500000000024), + new Point(352.30078125000006, 303.2500000000024), + new Point(355.3884058270521, 294.6010574408111), + new Point(361.97420124112136, 270.0327170981076), + new Point(364.88671875000006, 278.7421875000024), + new Point(364.88671875000006, 278.7421875000024), + new Point(375.3664019506479, 310.0801933245292), + new Point(357.8971646610286, 378.0230573842453), + new Point(350.98828125000006, 411.8945312500024), + new Point(350.98828125000006, 411.8945312500024), + new Point(349.44549763074656, 419.4581782145244), + new Point(346.68994122382514, 441.7180224628589), + new Point(344.84375000000006, 434.2226562500024), + new Point(344.84375000000006, 434.2226562500024), + new Point(334.8699062778416, 393.72976998630844), + new Point(348.64654655424886, 333.93685912922194), + new Point(363.42187500000006, 295.7031250000024), + new Point(363.42187500000006, 295.7031250000024), + new Point(366.01385854326765, 288.99591642427), + new Point(374.78764088252086, 271.72438714300574), + new Point(376.65625000000006, 278.6679687500024), + new Point(376.65625000000006, 278.6679687500024), + new Point(386.0404409111068, 313.5387690674105), + new Point(376.5072414130649, 359.9140684810038), + new Point(371.35546875000006, 395.3164062500024), + new Point(371.35546875000006, 395.3164062500024), + new Point(370.47114623523635, 401.39336003114414), + new Point(368.27444928800094, 419.5492437297912), + new Point(367.92968750000006, 413.4179687500024), + new Point(367.92968750000006, 413.4179687500024), + new Point(367.57559598429674, 407.12077304459694), + new Point(381.2496227510576, 314.3192924855825), + new Point(394.19921875000006, 321.8828125000024), + new Point(394.19921875000006, 321.8828125000024), + new Point(398.9599912315896, 324.6634550738358), + new Point(399.41010652732086, 361.3353304064885), + new Point(399.40625, 373.5585937500024), + new Point(399.40625, 373.5585937500024), + new Point(399.4021062327914, 386.69226391778363), + new Point(402.4735910546126, 437.84585593250733), + new Point(391.30078125, 451.4882812500024), + new Point(391.30078125, 451.4882812500024), + new Point(389.8551875223749, 453.2534061213149), + new Point(386.66818773224065, 448.9346865700609), + new Point(386.44531250000006, 446.6640625000024), + new Point(386.44531250000006, 446.6640625000024), + new Point(384.63625052499253, 428.23357283372593), + new Point(384.0183597236686, 409.5864912694675), + new Point(385.37500000000006, 391.1171875000024), + new Point(385.37500000000006, 391.1171875000024), + new Point(387.5057301634755, 362.10942226808237), + new Point(391.1069932337215, 333.12855724488816), + new Point(396.87890625, 304.6210937500024), + new Point(396.87890625, 304.6210937500024), + new Point(398.7369030851413, 295.44445217518665), + new Point(413.31296622434655, 273.6876837606645), + new Point(414.73828125, 282.9414062500024), + new Point(414.73828125, 282.9414062500024), + new Point(422.47658961682765, 333.1816386721019), + new Point(416.3226123598554, 344.40888616703336), + new Point(406.17187500000006, 388.1367187500024), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(360.31640624999994, 419.79687500000165), + new Point(360.31640624999994, 387.28804170711203), + new Point(353.8375997408046, 338.1159964274532), + new Point(373.19140624999994, 311.47656250000165), + new Point(373.19140624999994, 311.47656250000165), + new Point(375.04452584288435, 308.9258468601168), + new Point(380.35166992218274, 303.41355955444885), + new Point(381.20312499999994, 306.44921875000165), + new Point(381.20312499999994, 306.44921875000165), + new Point(389.74470652742275, 336.90218236935914), + new Point(377.840715245988, 405.29626580764153), + new Point(374.69140624999994, 436.6718750000016), + new Point(374.69140624999994, 436.6718750000016), + new Point(374.3637887991069, 439.9358281773219), + new Point(372.2828530873304, 449.5088251719086), + new Point(373.41406249999994, 446.4296875000016), + new Point(373.41406249999994, 446.4296875000016), + new Point(384.47748465349423, 416.31519273758323), + new Point(391.44639059744276, 384.736171865222), + new Point(403.29296874999994, 354.76562500000165), + new Point(403.29296874999994, 354.76562500000165), + new Point(408.66573789471227, 341.17310677457203), + new Point(415.04361640750955, 330.72319025506334), + new Point(415.13671874999994, 330.80859375000165), + new Point(415.13671874999994, 330.80859375000165), + new Point(426.0479963297067, 340.8175926067711), + new Point(408.61316521731925, 414.94664127793095), + new Point(407.59765624999994, 421.33593750000165), + new Point(407.59765624999994, 421.33593750000165), + new Point(406.6611602278542, 427.2281065392128), + new Point(403.1719958538481, 444.7624010597073), + new Point(403.82421874999994, 438.83203125000165), + new Point(403.82421874999994, 438.83203125000165), + new Point(408.025237111059, 400.63405843206505), + new Point(420.46854636140046, 363.2070690381559), + new Point(432.55468749999994, 327.00000000000165), + new Point(432.55468749999994, 327.00000000000165), + new Point(433.9543160796147, 322.80706132513876), + new Point(435.4460375757543, 310.9274198363807), + new Point(437.65234374999994, 314.75781250000165), + new Point(437.65234374999994, 314.75781250000165), + new Point(447.3583612905008, 331.60853739670455), + new Point(436.0080565477229, 386.5722433998543), + new Point(426.58984374999994, 403.64843750000165), + new Point(426.58984374999994, 403.64843750000165), + new Point(419.44319318371674, 416.6060542853524), + new Point(434.55620477566094, 343.87325134449804), + new Point(445.03124999999994, 324.32421875000165), + new Point(445.03124999999994, 324.32421875000165), + new Point(446.776049746441, 321.0679896470674), + new Point(451.26093646271016, 312.506335701064), + new Point(452.37890624999994, 316.02734375000165), + new Point(452.37890624999994, 316.02734375000165), + new Point(461.46142860081767, 344.63244083353794), + new Point(442.92616409886824, 409.6331277041565), + new Point(436.23828124999994, 441.69531250000165), + new Point(436.23828124999994, 441.69531250000165), + new Point(435.25232133569, 446.4220742702455), + new Point(431.2264596787497, 460.3318808280576), + new Point(432.15624999999994, 455.5937500000016), + new Point(432.15624999999994, 455.5937500000016), + new Point(434.4638884648937, 443.83422454503824), + new Point(468.42500825154286, 338.71542793756396), + new Point(475.89453124999994, 336.11328125000165), + new Point(475.89453124999994, 336.11328125000165), + new Point(476.685457911257, 335.83774729795147), + new Point(480.4587064668621, 352.5174392527946), + new Point(465.97656249999994, 424.65234375000165), + new Point(465.97656249999994, 424.65234375000165), + new Point(465.81280429119914, 425.46801598606766), + new Point(456.5300671119099, 467.0743115613128), + new Point(454.58203124999994, 473.7421875000016), + new Point(454.58203124999994, 473.7421875000016), + new Point(453.21079407358985, 478.4357558031313), + new Point(450.83629310855844, 492.27631289183245), + new Point(449.60937499999994, 487.54296875000165), + new Point(449.60937499999994, 487.54296875000165), + new Point(444.9610285309702, 469.61004936858313), + new Point(479.30458452118523, 336.0909300056036), + new Point(476.78124999999994, 421.22656250000165), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(318.01953125000006, 571.7031249999968), + new Point(317.2829670283564, 531.1828857568246), + new Point(317.1419163854665, 492.3928975316594), + new Point(329.11328125000006, 452.6679687499969), + new Point(329.11328125000006, 452.6679687499969), + new Point(331.7668651914233, 443.86250385254823), + new Point(329.11328125000006, 471.06119791666356), + new Point(329.11328125000006, 480.2578124999969), + new Point(329.11328125000006, 480.2578124999969), + new Point(329.11328125000006, 494.2539062499969), + new Point(328.33289710338437, 508.2717729850187), + new Point(329.11328125000006, 522.2460937499968), + new Point(329.11328125000006, 522.2460937499968), + new Point(329.16059502946604, 523.0933404985738), + new Point(329.27092936086177, 520.5522817922881), + new Point(329.44921875000006, 519.7226562499968), + new Point(329.44921875000006, 519.7226562499968), + new Point(331.63351501757506, 509.5585742243075), + new Point(333.4761409937016, 499.3066105346174), + new Point(336.19921875000006, 489.2734374999969), + new Point(336.19921875000006, 489.2734374999969), + new Point(336.539461963532, 488.01981224918444), + new Point(348.82054189245895, 437.78913850925323), + new Point(358.38281250000006, 422.2929687499969), + new Point(358.38281250000006, 422.2929687499969), + new Point(359.24876587296694, 420.8896451021059), + new Point(361.87383434816996, 417.6199278900744), + new Point(362.26171875000006, 419.2226562499969), + new Point(362.26171875000006, 419.2226562499969), + new Point(368.35304296925545, 444.3918510658259), + new Point(354.7904161066247, 483.0734735411416), + new Point(349.25390625000006, 506.5507812499969), + new Point(349.25390625000006, 506.5507812499969), + new Point(348.5474948069061, 509.5462855023246), + new Point(349.00883558407105, 517.3718647847758), + new Point(346.64062500000006, 515.4062499999968), + new Point(346.64062500000006, 515.4062499999968), + new Point(338.393631919145, 508.56124574288714), + new Point(360.27609575678457, 456.08074611785366), + new Point(363.50390625000006, 447.0781249999969), + new Point(363.50390625000006, 447.0781249999969), + new Point(366.15840144117874, 439.67452602304814), + new Point(372.00491145353607, 417.9422624785703), + new Point(373.43750000000006, 425.6757812499969), + new Point(373.43750000000006, 425.6757812499969), + new Point(379.1237655949397, 456.3718536333233), + new Point(368.40557020133133, 493.3411076273632), + new Point(361.91796875000006, 522.9921874999968), + new Point(361.91796875000006, 522.9921874999968), + new Point(361.59558951839495, 524.465596805009), + new Point(360.3229673286539, 528.7869018713391), + new Point(360.50000000000006, 527.2890624999968), + new Point(360.50000000000006, 527.2890624999968), + new Point(364.1841847875026, 496.11788384659036), + new Point(373.93071880469427, 465.6242107816397), + new Point(386.19531250000006, 436.8749999999969), + new Point(386.19531250000006, 436.8749999999969), + new Point(387.4453742674153, 433.9447529706763), + new Point(390.85007972097424, 425.93833639254126), + new Point(391.64453125000006, 429.0234374999969), + new Point(391.64453125000006, 429.0234374999969), + new Point(398.24151943007934, 454.6415838520982), + new Point(398.48240138964064, 509.9408726631595), + new Point(386.66406250000006, 536.1054687499968), + new Point(386.66406250000006, 536.1054687499968), + new Point(385.2315061208437, 539.2770023624832), + new Point(385.8480019347523, 529.1233743507023), + new Point(386.29296875000006, 525.6718749999968), + new Point(386.29296875000006, 525.6718749999968), + new Point(390.6100512292364, 492.1853163097045), + new Point(396.8491874320404, 434.27780060002965), + new Point(421.25390625000006, 407.2460937499969), + new Point(421.25390625000006, 407.2460937499969), + new Point(436.4856519579619, 390.37476292815325), + new Point(418.58943004183317, 551.3623236004642), + new Point(410.32812500000006, 574.5859374999968), + new Point(410.32812500000006, 574.5859374999968), + new Point(409.5835745454071, 576.6789666520049), + new Point(408.53466554420066, 570.3599703056349), + new Point(408.63281250000006, 568.1406249999968), + new Point(408.63281250000006, 568.1406249999968), + new Point(410.52187997370754, 525.4241393417512), + new Point(422.1134774899829, 487.31686826895407), + new Point(440.47656250000006, 448.7421874999969), + new Point(440.47656250000006, 448.7421874999969), + new Point(442.23375655255893, 445.050912336287), + new Point(447.27773995442345, 435.1473662570927), + new Point(448.11718750000006, 439.1484374999969), + new Point(448.11718750000006, 439.1484374999969), + new Point(451.42972960611144, 454.9370558973121), + new Point(448.45052083333337, 471.4114583333302), + new Point(448.6171875, 487.5429687499969), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(286.0625, 419.27734375), + new Point(286.0625, 478.7421875), + new Point(286.0625, 538.20703125), + new Point(286.0625, 597.671875), + new Point(286.0625, 597.671875), + new Point(286.0625, 601.5078125), + new Point(286.0625, 613.015625), + new Point(286.0625, 609.1796875), + new Point(286.0625, 609.1796875), + new Point(286.0625, 579.5015005805797), + new Point(285.92189941671097, 549.8183039635979), + new Point(286.0625, 520.140625), + new Point(286.0625, 520.140625), + new Point(286.14236513557603, 503.28285813614184), + new Point(286.14622450433006, 483.96479936346583), + new Point(288.375, 483.0625), + new Point(288.375, 483.0625), + new Point(303.9236370671834, 476.76777657193935), + new Point(309.3935147547387, 567.5334178479935), + new Point(316.66796875, 573.7421875), + new Point(316.66796875, 573.7421875), + new Point(320.81795714165287, 577.2842158087993), + new Point(317.8770617755209, 562.8971472486874), + new Point(318.53125, 557.48046875), + new Point(318.53125, 557.48046875), + new Point(319.94986035764225, 545.7343749887222), + new Point(321.3486479695534, 531.8306107643916), + new Point(326.0703125, 520.62890625), + new Point(326.0703125, 520.62890625), + new Point(327.3398957612232, 517.6169395045999), + new Point(329.4763274846858, 510.0910678537499), + new Point(331.62890625, 512.55078125), + new Point(331.62890625, 512.55078125), + new Point(343.34515135602646, 525.9387257495991), + new Point(346.17491351252727, 547.110017874155), + new Point(349.67578125, 563.8046875), + new Point(349.67578125, 563.8046875), + new Point(351.5417763798504, 572.703101993881), + new Point(352.8594474008135, 599.2656357516478), + new Point(355.2734375, 590.5), + new Point(355.2734375, 590.5), + new Point(362.2198662179763, 565.276257807733), + new Point(339.9115182514421, 500.75515568686217), + new Point(361.12890625, 480.66796875), + new Point(361.12890625, 480.66796875), + new Point(365.6304801454423, 476.40618325811977), + new Point(374.4718350424577, 534.8275553996313), + new Point(375.9765625, 546.31640625), + new Point(375.9765625, 546.31640625), + new Point(376.0755838424148, 547.072451092742), + new Point(376.32348781237187, 549.3315610584825), + new Point(376.3671875, 548.5703125), + new Point(376.3671875, 548.5703125), + new Point(377.605977644378, 526.990588184935), + new Point(380.90167131009645, 449.5514989469243), + new Point(391.71875, 462.140625), + new Point(391.71875, 462.140625), + new Point(399.0813174226346, 470.70932381554326), + new Point(397.48323927925884, 500.43895433861707), + new Point(398.83203125, 511.9765625), + new Point(398.83203125, 511.9765625), + new Point(399.19472782426254, 515.0790801944207), + new Point(399.8966194769696, 524.3999666798851), + new Point(399.9765625, 521.27734375), + new Point(399.9765625, 521.27734375), + new Point(400.2893636877161, 509.0591397813308), + new Point(396.14429789379636, 457.7920119603579), + new Point(410.11328125, 450.6484375), + new Point(410.11328125, 450.6484375), + new Point(424.91778292248904, 443.07758875967613), + new Point(425.57401530105625, 516.7850434504185), + new Point(426.015625, 511.9609375), + new Point(426.015625, 511.9609375), + new Point(427.1704096746567, 499.3461701301087), + new Point(418.45747990469425, 461.9373890541116), + new Point(429.65625, 452.859375), + new Point(429.65625, 452.859375), + new Point(434.37687840243507, 449.03271094521176), + new Point(445.3545774005855, 502.9627794573321), + new Point(445.9296875, 504.75390625), + new Point(445.9296875, 504.75390625), + new Point(448.2046293797787, 511.8390006637174), + new Point(446.4200902790616, 489.87825241657424), + new Point(446.515625, 482.4375), + new Point(446.515625, 482.4375), + new Point(446.7074408712635, 467.4978592743905), + new Point(447.0130208333333, 452.5598958333333), + new Point(447.26171875, 437.62109375), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(263.19140625, 434.19531250000006), + new Point(263.84809172429374, 465.69067749765594), + new Point(264.59765625, 496.83121033110893), + new Point(264.59765625, 528.234375), + new Point(264.59765625, 528.234375), + new Point(264.59765625, 529.61328125), + new Point(264.59765625, 525.4765625), + new Point(264.59765625, 524.09765625), + new Point(264.59765625, 524.09765625), + new Point(264.59765625, 507.62239583333337), + new Point(264.4918239792684, 491.14679549533037), + new Point(264.59765625, 474.67187500000006), + new Point(264.59765625, 474.67187500000006), + new Point(264.6233067812299, 470.67885415905687), + new Point(265.00069760186, 459.39652816246775), + new Point(266.890625, 462.91406250000006), + new Point(266.890625, 462.91406250000006), + new Point(278.4656260741293, 484.4574634662459), + new Point(275.4691019474388, 512.9578803758861), + new Point(283.80078125, 535.8671875), + new Point(283.80078125, 535.8671875), + new Point(284.8635638796295, 538.7894811678409), + new Point(283.35493154233217, 490.7350624271325), + new Point(296.66015625, 465.15625000000006), + new Point(296.66015625, 465.15625000000006), + new Point(299.03708414247933, 460.58669224728436), + new Point(314.4525786767557, 516.5086697437598), + new Point(318.0078125, 527.33203125), + new Point(318.0078125, 527.33203125), + new Point(318.253005959178, 528.078484951666), + new Point(318.8772700014602, 530.2336435879263), + new Point(319.01953125, 529.4609375), + new Point(319.01953125, 529.4609375), + new Point(323.2506297765762, 506.47930600401094), + new Point(316.1003988179876, 455.46572838768935), + new Point(330.20703125, 440.15234375000006), + new Point(330.20703125, 440.15234375000006), + new Point(345.5401584680231, 423.50754380076694), + new Point(356.11452107069823, 506.7365105991001), + new Point(357.72265625, 514.44921875), + new Point(357.72265625, 514.44921875), + new Point(357.9284779247672, 515.4363512554266), + new Point(358.4088745321983, 518.394421791365), + new Point(358.4453125, 517.38671875), + new Point(358.4453125, 517.38671875), + new Point(359.11133408957244, 498.96768986564945), + new Point(355.77796309761226, 475.0472293196765), + new Point(363.4375, 457.02734375000006), + new Point(363.4375, 457.02734375000006), + new Point(364.21193067941846, 455.2054121629328), + new Point(365.5041091670718, 451.20079863617616), + new Point(367.109375, 452.35937500000006), + new Point(367.109375, 452.35937500000006), + new Point(380.1191967240991, 461.7490172872275), + new Point(372.6718969270413, 491.9805562003667), + new Point(380.8515625, 504.50390625000006), + new Point(380.8515625, 504.50390625000006), + new Point(382.2489662703702, 506.6433796087737), + new Point(381.00618198887264, 499.392137523082), + new Point(381.2421875, 496.84765625000006), + new Point(381.2421875, 496.84765625000006), + new Point(383.2541403446656, 475.15589019283686), + new Point(382.9012293950138, 440.23721480916214), + new Point(402.7265625, 425.11718750000006), + new Point(402.7265625, 425.11718750000006), + new Point(405.0899690010757, 423.3147072768593), + new Point(407.9416087288579, 428.7075966660243), + new Point(408.94921875, 431.50390625000006), + new Point(408.94921875, 431.50390625000006), + new Point(413.8646985258712, 445.14529817614135), + new Point(416.2962409807787, 459.55881370353956), + new Point(420.171875, 473.53125000000006), + new Point(420.171875, 473.53125000000006), + new Point(422.7224436458358, 482.7265604310018), + new Point(421.7544325389145, 443.5546637052386), + new Point(422.45703125, 444.46093750000006), + new Point(422.45703125, 444.46093750000006), + new Point(428.8115111787907, 452.6575062496114), + new Point(432.0113940756172, 462.89903743512724), + new Point(436, 472.47265625000006), + new Point(436, 472.47265625000006), + new Point(441.34823302082475, 485.3097089057886), + new Point(434.7717028155082, 481.26946043594654), + new Point(440.7421875, 484.32031250000006), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(198.85156250000003, 505.33203125000006), + new Point(199.75889922937318, 544.4060484665531), + new Point(199.09375000000003, 583.5242240174564), + new Point(199.09375000000003, 622.609375), + new Point(199.09375000000003, 622.609375), + new Point(199.09375000000003, 629.5675673896105), + new Point(194.19106222690937, 551.7442875660684), + new Point(201.22656250000003, 544.828125), + new Point(201.22656250000003, 544.828125), + new Point(205.57354017532955, 540.5548817185465), + new Point(208.30618071459148, 554.9518610077989), + new Point(210.26953125000003, 560.72265625), + new Point(210.26953125000003, 560.72265625), + new Point(214.2662037605245, 572.4699109008725), + new Point(217.07535868244895, 584.5926859835965), + new Point(220.85937500000003, 596.41015625), + new Point(220.85937500000003, 596.41015625), + new Point(222.8412601667259, 602.5995769775425), + new Point(226.71178806695914, 621.0915019213014), + new Point(227.69921875000003, 614.66796875), + new Point(227.69921875000003, 614.66796875), + new Point(230.31056548250922, 597.6803739282707), + new Point(230.91874641618037, 518.854436551373), + new Point(251.82812500000003, 578.4375), + new Point(251.82812500000003, 578.4375), + new Point(253.14358121361983, 582.1860050416874), + new Point(260.0977393370173, 626.2477098035608), + new Point(262.21484375, 626.875), + new Point(262.21484375, 626.875), + new Point(268.73953343727123, 628.8082413888212), + new Point(257.6813242488604, 577.6952818714917), + new Point(263.9921875, 566.75390625), + new Point(263.9921875, 566.75390625), + new Point(266.10011105210697, 563.0993216952127), + new Point(272.04150889573884, 559.4788778831501), + new Point(275.609375, 561.73046875), + new Point(275.609375, 561.73046875), + new Point(286.670546424392, 568.7108967784168), + new Point(282.21424936552216, 587.0546305673276), + new Point(284.84375, 599.8671875), + new Point(284.84375, 599.8671875), + new Point(285.2680610986764, 601.934694173196), + new Point(286.1251761656762, 608.1454887044961), + new Point(286.2578125, 606.0390625), + new Point(286.2578125, 606.0390625), + new Point(287.02837379899745, 593.8016124780768), + new Point(279.15702960625924, 544.6288043914185), + new Point(294.4140625, 534.98046875), + new Point(294.4140625, 534.98046875), + new Point(299.1762637411948, 531.9689188446528), + new Point(307.51677342252935, 593.7918300260496), + new Point(308.4921875, 587.640625), + new Point(308.4921875, 587.640625), + new Point(312.047722049679, 565.2185352460874), + new Point(305.2914022439636, 539.6343424602633), + new Point(316.55859375, 518.42578125), + new Point(316.55859375, 518.42578125), + new Point(316.66118558583923, 518.2326696632392), + new Point(329.6565427162958, 551.7857882206397), + new Point(332.875, 562.1875), + new Point(332.875, 562.1875), + new Point(333.784178750494, 565.1258690647196), + new Point(335.0561046661562, 573.9344232382725), + new Point(335.78125, 570.9453125), + new Point(335.78125, 570.9453125), + new Point(341.29463710003074, 548.2186619710667), + new Point(332.20630321028193, 521.6827517917106), + new Point(336.61328125, 498.32031250000006), + new Point(336.61328125, 498.32031250000006), + new Point(339.0323741412791, 485.49612542573686), + new Point(352.69670371333996, 519.0382874373265), + new Point(358.828125, 530.55859375), + new Point(358.828125, 530.55859375), + new Point(359.72565957011113, 532.244968358835), + new Point(362.0204981516101, 536.8664207855863), + new Point(362.4453125, 535.00390625), + new Point(362.4453125, 535.00390625), + new Point(364.96882306295765, 523.9400730201955), + new Point(364.51302083333337, 512.40234375), + new Point(365.546875, 501.10156250000006), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(282.51953125, 366.08203125000006), + new Point(282.51953125, 399.0171936365168), + new Point(281.465208674747, 432.563541326739), + new Point(284.02734375, 465.45312500000006), + new Point(284.02734375, 465.45312500000006), + new Point(284.4948554947623, 471.4544739515472), + new Point(284.02734375, 453.4140625), + new Point(284.02734375, 447.39453125000006), + new Point(284.02734375, 447.39453125000006), + new Point(284.02734375, 438.84895833333337), + new Point(275.4868486716554, 421.46326150129426), + new Point(284.02734375, 421.75781250000006), + new Point(284.02734375, 421.75781250000006), + new Point(351.0120264392244, 424.0680304678241), + new Point(317.0547356623472, 455.7081120208647), + new Point(340.4375, 482.34375), + new Point(340.4375, 482.34375), + new Point(342.4112055208514, 484.59202590834354), + new Point(340.8771559369096, 476.37382068125686), + new Point(340.94140625, 473.38281250000006), + new Point(340.94140625, 473.38281250000006), + new Point(341.4618390773588, 449.1553999077127), + new Point(335.4704017465078, 391.99616209526295), + new Point(351.4921875, 383.37890625000006), + new Point(351.4921875, 383.37890625000006), + new Point(364.08562841908304, 376.6055724879825), + new Point(376.4631811605358, 451.8834325191626), + new Point(375.9765625, 441.78906250000006), + new Point(375.9765625, 441.78906250000006), + new Point(374.43473132283873, 409.80546698352026), + new Point(369.0393659766197, 349.880748888313), + new Point(380.7890625, 362.93750000000006), + new Point(380.7890625, 362.93750000000006), + new Point(393.42468435238794, 376.97872815765805), + new Point(383.70773624681044, 410.9144679084301), + new Point(396.8359375, 422.68750000000006), + new Point(396.8359375, 422.68750000000006), + new Point(398.8979964730301, 424.53670127258835), + new Point(396.9147184768363, 417.1485084886875), + new Point(396.9453125, 414.37890625000006), + new Point(396.9453125, 414.37890625000006), + new Point(397.0279370404215, 406.89910828759366), + new Point(395.6226159567791, 368.60673084397666), + new Point(400.72265625, 356.62890625000006), + new Point(400.72265625, 356.62890625000006), + new Point(401.45840018557703, 354.90095680259316), + new Point(403.9450202904366, 358.960192577903), + new Point(404.59375, 360.72265625000006), + new Point(404.59375, 360.72265625000006), + new Point(411.5554040981526, 379.63602227104633), + new Point(414.9338562806529, 396.92841725935807), + new Point(419.09375, 416.00781250000006), + new Point(419.09375, 416.00781250000006), + new Point(419.3831032739092, 417.33493426068634), + new Point(420.071191736513, 421.2920627948762), + new Point(420.171875, 419.93750000000006), + new Point(420.171875, 419.93750000000006), + new Point(421.3367375787124, 404.2657840104709), + new Point(413.82939616953115, 386.60817827662805), + new Point(418.82421875, 371.45703125000006), + new Point(418.82421875, 371.45703125000006), + new Point(419.21692821691227, 370.2657979727254), + new Point(421.133935187437, 368.0483000102584), + new Point(421.77734375, 369.12500000000006), + new Point(421.77734375, 369.12500000000006), + new Point(429.5845915521686, 382.18989238349553), + new Point(433.47161371734524, 395.7388687307912), + new Point(437.7890625, 409.90625000000006), + new Point(437.7890625, 409.90625000000006), + new Point(439.54174280899235, 415.65753772350183), + new Point(442.60156998314767, 433.1164044473312), + new Point(443.1484375, 427.12890625000006), + new Point(443.1484375, 427.12890625000006), + new Point(444.9988632108503, 406.8691170568441), + new Point(434.01421924349546, 360.8651425318102), + new Point(451.1015625, 344.83203125000006), + new Point(451.1015625, 344.83203125000006), + new Point(454.3981201265483, 341.7388602122362), + new Point(456.74791905778216, 352.02694535477997), + new Point(458.515625, 356.18750000000006), + new Point(458.515625, 356.18750000000006), + new Point(463.3024469980147, 367.4539861411816), + new Point(466.43627239553916, 379.3553928896255), + new Point(470.65234375, 390.84765625000006), + new Point(470.65234375, 390.84765625000006), + new Point(471.5820581514773, 393.381892948913), + new Point(473.2969420337604, 400.8664640011172), + new Point(473.9453125, 398.24609375000006), + new Point(473.9453125, 398.24609375000006), + new Point(476.87790725092657, 386.3940979481578), + new Point(483.479828431496, 318.19776501848423), + new Point(484.625, 307.11328125000006), + ]) + ) + ); + this.Multistrokes.push( + new Multistroke( + Gestures.Scribble, + useBoundedRotationInvariance, + new Array([ + new Point(259.828125, 289.8710937500002), + new Point(259.828125, 346.12760416666686), + new Point(259.828125, 402.38411458333366), + new Point(259.828125, 458.6406250000002), + new Point(259.828125, 458.6406250000002), + new Point(259.828125, 468.19270833333354), + new Point(259.828125, 439.5364583333335), + new Point(259.828125, 429.9843750000002), + new Point(259.828125, 429.9843750000002), + new Point(259.828125, 420.10807291666686), + new Point(259.7698694850355, 410.23159902132767), + new Point(259.828125, 400.3554687500002), + new Point(259.828125, 400.3554687500002), + new Point(259.89487138298495, 389.0398710095856), + new Point(249.63776002911712, 370.46234952458104), + new Point(260.203125, 366.4101562500002), + new Point(260.203125, 366.4101562500002), + new Point(270.2545569338826, 362.5550745756203), + new Point(295.64963161626537, 463.293791500702), + new Point(296.5078125, 455.8750000000002), + new Point(296.5078125, 455.8750000000002), + new Point(298.7836092036059, 436.2012207746192), + new Point(296.79259637155917, 387.4347876167413), + new Point(312.3359375, 368.4609375000002), + new Point(312.3359375, 368.4609375000002), + new Point(313.9568151037837, 366.48232244821446), + new Point(316.3733700547079, 371.999994680037), + new Point(317.1484375, 374.4375000000002), + new Point(317.1484375, 374.4375000000002), + new Point(324.93749841786456, 398.9332745808258), + new Point(324.6280259723674, 404.5930082467283), + new Point(328.140625, 424.1210937500002), + new Point(328.140625, 424.1210937500002), + new Point(328.6908430171252, 427.1799981109408), + new Point(328.93583340463675, 436.21035749587384), + new Point(329.94140625, 433.2695312500002), + new Point(329.94140625, 433.2695312500002), + new Point(336.6512632639073, 413.64636451121464), + new Point(321.4476838274886, 382.3696268208617), + new Point(332.796875, 363.7773437500002), + new Point(332.796875, 363.7773437500002), + new Point(342.67240046179427, 347.5992247925989), + new Point(346.14555519919713, 399.4672567304212), + new Point(349.5703125, 418.1093750000002), + new Point(349.5703125, 418.1093750000002), + new Point(349.7235934255364, 418.9437351871151), + new Point(350.05059429345636, 421.4491489685843), + new Point(350.0859375, 420.6015625000002), + new Point(350.0859375, 420.6015625000002), + new Point(350.7585773994656, 404.47058478827614), + new Point(345.7392083746819, 379.4896927503583), + new Point(352.51171875, 364.4257812500002), + new Point(352.51171875, 364.4257812500002), + new Point(359.2282991251986, 349.4862733349193), + new Point(370.1176408160291, 432.0397667858392), + new Point(375.97265625, 438.0859375000002), + new Point(375.97265625, 438.0859375000002), + new Point(378.06739094903344, 440.2490613609126), + new Point(375.9551753749695, 432.05802890075626), + new Point(376.171875, 429.0546875000002), + new Point(376.171875, 429.0546875000002), + new Point(376.88428931505103, 419.181004485632), + new Point(375.6725775283135, 350.9394248693232), + new Point(390.58984375, 331.6679687500002), + new Point(390.58984375, 331.6679687500002), + new Point(391.3989549288357, 330.6226867025485), + new Point(393.62948037226954, 332.226953546521), + new Point(394.1328125, 333.4492187500002), + new Point(394.1328125, 333.4492187500002), + new Point(400.5203577599557, 348.9603969100286), + new Point(398.33028866604764, 399.7279234608218), + new Point(404.69140625, 401.2578125000002), + new Point(404.69140625, 401.2578125000002), + new Point(405.96227039672993, 401.56346337073273), + new Point(404.9167737667878, 398.650789161509), + new Point(404.9296875, 397.3437500000002), + new Point(404.9296875, 397.3437500000002), + new Point(404.9962208375517, 390.6097036714085), + new Point(404.8044426323719, 383.8738352569102), + new Point(404.9296875, 377.1406250000002), + new Point(404.9296875, 377.1406250000002), + new Point(405.2014454587436, 362.53081695067664), + new Point(405.10877613603685, 348.31042553528835), + new Point(408.359375, 334.0117187500002), + new Point(408.359375, 334.0117187500002), + new Point(409.1987960150188, 330.3192806899779), + new Point(408.89694776402825, 321.5616495931396), + new Point(412.2421875, 323.3359375000002), + new Point(412.2421875, 323.3359375000002), + new Point(426.02454279155006, 330.64598648061565), + new Point(427.04330065072827, 378.56788178137765), + new Point(430.05078125, 389.4687500000002), + new Point(430.05078125, 389.4687500000002), + new Point(430.70947957030876, 391.85625786530534), + new Point(430.37782234767565, 384.51859565608413), + new Point(430.3046875, 382.0429687500002), + new Point(430.3046875, 382.0429687500002), + new Point(429.60422098259426, 358.3320592121596), + new Point(428.5885416666667, 334.6315104166669), + new Point(427.73046875, 310.9257812500002), + ]) + ) + ); + + this.Multistrokes.push(new Multistroke(Gestures.RightAngle, useBoundedRotationInvariance, new Array([new Point(200, 0), new Point(0, 0), new Point(0, 100)]))); NumMultistrokes = this.Multistrokes.length; // NumMultistrokes flags the end of the non user-defined gstures strokes // // PREDEFINED STROKES |
