From ef94ad7df2a087141ddb8d347d3e3c484ff7609b Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Tue, 3 Dec 2019 01:46:36 -0500
Subject: const linter rule and restored google docs push, fixed routing

---
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 231 +++++++++++----------
 1 file changed, 122 insertions(+), 109 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 9506ce084..c69b264c4 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,12 +1,12 @@
 import { library } from "@fortawesome/fontawesome-svg-core";
 import { faEye } from "@fortawesome/free-regular-svg-icons";
 import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrowsAlt, faFileUpload, faPaintBrush, faTable, faUpload } from "@fortawesome/free-solid-svg-icons";
-import { action, computed, observable, trace, ObservableMap, untracked, reaction, runInAction, IReactionDisposer } from "mobx";
+import { action, computed, observable, ObservableMap, reaction, runInAction, IReactionDisposer } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../../new_fields/Doc";
+import { Doc, DocListCast, HeightSym, Opt, WidthSym, DocListCastAsync } from "../../../../new_fields/Doc";
 import { documentSchema, positionSchema } from "../../../../new_fields/documentSchemas";
 import { Id } from "../../../../new_fields/FieldSymbols";
-import { InkTool } from "../../../../new_fields/InkField";
+import { InkTool, InkField, InkData } from "../../../../new_fields/InkField";
 import { createSchema, makeInterface } from "../../../../new_fields/Schema";
 import { ScriptField } from "../../../../new_fields/ScriptField";
 import { BoolCast, Cast, DateCast, NumCast, StrCast } from "../../../../new_fields/Types";
@@ -26,7 +26,7 @@ import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss"
 import { ContextMenu } from "../../ContextMenu";
 import { ContextMenuProps } from "../../ContextMenuItem";
 import { InkingControl } from "../../InkingControl";
-import { CreatePolyline, InkingStroke } from "../../InkingStroke";
+import { CreatePolyline } from "../../InkingStroke";
 import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView";
 import { DocumentViewProps } from "../../nodes/DocumentView";
 import { FormattedTextBox } from "../../nodes/FormattedTextBox";
@@ -39,8 +39,9 @@ import "./CollectionFreeFormView.scss";
 import MarqueeOptionsMenu from "./MarqueeOptionsMenu";
 import { MarqueeView } from "./MarqueeView";
 import React = require("react");
-import { computedFn, keepAlive } from "mobx-utils";
+import { computedFn } from "mobx-utils";
 import { TraceMobx } from "../../../../new_fields/util";
+import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
 
 library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload);
 
@@ -98,10 +99,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     private getLocalTransform = (): Transform => Transform.Identity().scale(1 / this.zoomScaling()).translate(this.panX(), this.panY());
     private addLiveTextBox = (newBox: Doc) => {
         FormattedTextBox.SelectOnLoad = newBox[Id];// track the new text box so we can give it a prop that tells it to focus itself when it's displayed
-        let maxHeading = this.childDocs.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0);
+        const maxHeading = this.childDocs.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0);
         let heading = maxHeading === 0 || this.childDocs.length === 0 ? 1 : maxHeading === 1 ? 2 : 0;
         if (heading === 0) {
-            let sorted = this.childDocs.filter(d => d.type === DocumentType.TEXT && d.data_ext instanceof Doc && d.data_ext.lastModified).sort((a, b) => DateCast((Cast(a.data_ext, Doc) as Doc).lastModified).date > DateCast((Cast(b.data_ext, Doc) as Doc).lastModified).date ? 1 :
+            const sorted = this.childDocs.filter(d => d.type === DocumentType.TEXT && d.data_ext instanceof Doc && d.data_ext.lastModified).sort((a, b) => DateCast((Cast(a.data_ext, Doc) as Doc).lastModified).date > DateCast((Cast(b.data_ext, Doc) as Doc).lastModified).date ? 1 :
                 DateCast((Cast(a.data_ext, Doc) as Doc).lastModified).date < DateCast((Cast(b.data_ext, Doc) as Doc).lastModified).date ? -1 : 0);
             heading = !sorted.length ? Math.max(1, maxHeading) : NumCast(sorted[sorted.length - 1].heading) === 1 ? 2 : NumCast(sorted[sorted.length - 1].heading);
         }
@@ -109,7 +110,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         this.addDocument(newBox);
     }
     private addDocument = (newBox: Doc) => {
-        let added = this.props.addDocument(newBox);
+        const added = this.props.addDocument(newBox);
         added && this.bringToFront(newBox);
         added && this.updateCluster(newBox);
         return added;
@@ -126,36 +127,36 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     @action
     onDrop = (e: React.DragEvent): Promise<void> => {
-        var pt = this.getTransform().transformPoint(e.pageX, e.pageY);
+        const pt = this.getTransform().transformPoint(e.pageX, e.pageY);
         return super.onDrop(e, { x: pt[0], y: pt[1] });
     }
 
     @undoBatch
     @action
     drop = (e: Event, de: DragManager.DropEvent) => {
-        let xf = this.getTransform();
-        let xfo = this.getTransformOverlay();
-        let [xp, yp] = xf.transformPoint(de.x, de.y);
-        let [xpo, ypo] = xfo.transformPoint(de.x, de.y);
+        const xf = this.getTransform();
+        const xfo = this.getTransformOverlay();
+        const [xp, yp] = xf.transformPoint(de.x, de.y);
+        const [xpo, ypo] = xfo.transformPoint(de.x, de.y);
         if (super.drop(e, de)) {
             if (de.data instanceof DragManager.DocumentDragData) {
                 if (de.data.droppedDocuments.length) {
-                    let firstDoc = de.data.droppedDocuments[0];
-                    let z = NumCast(firstDoc.z);
-                    let x = (z ? xpo : xp) - de.data.offset[0];
-                    let y = (z ? ypo : yp) - de.data.offset[1];
-                    let dropX = NumCast(firstDoc.x);
-                    let dropY = NumCast(firstDoc.y);
+                    const firstDoc = de.data.droppedDocuments[0];
+                    const z = NumCast(firstDoc.z);
+                    const x = (z ? xpo : xp) - de.data.offset[0];
+                    const y = (z ? ypo : yp) - de.data.offset[1];
+                    const dropX = NumCast(firstDoc.x);
+                    const dropY = NumCast(firstDoc.y);
                     de.data.droppedDocuments.forEach(action((d: Doc) => {
-                        let layoutDoc = Doc.Layout(d);
+                        const layoutDoc = Doc.Layout(d);
                         d.x = x + NumCast(d.x) - dropX;
                         d.y = y + NumCast(d.y) - dropY;
                         if (!NumCast(layoutDoc.width)) {
                             layoutDoc.width = 300;
                         }
                         if (!NumCast(layoutDoc.height)) {
-                            let nw = NumCast(layoutDoc.nativeWidth);
-                            let nh = NumCast(layoutDoc.nativeHeight);
+                            const nw = NumCast(layoutDoc.nativeWidth);
+                            const nh = NumCast(layoutDoc.nativeHeight);
                             layoutDoc.height = nw && nh ? nh / nw * NumCast(layoutDoc.width) : 300;
                         }
                         this.bringToFront(d);
@@ -166,11 +167,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             }
             else if (de.data instanceof DragManager.AnnotationDragData) {
                 if (de.data.dropDocument) {
-                    let dragDoc = de.data.dropDocument;
-                    let x = xp - de.data.offset[0];
-                    let y = yp - de.data.offset[1];
-                    let dropX = NumCast(dragDoc.x);
-                    let dropY = NumCast(dragDoc.y);
+                    const dragDoc = de.data.dropDocument;
+                    const x = xp - de.data.offset[0];
+                    const y = yp - de.data.offset[1];
+                    const dropX = NumCast(dragDoc.x);
+                    const dropY = NumCast(dragDoc.y);
                     dragDoc.x = x + NumCast(dragDoc.x) - dropX;
                     dragDoc.y = y + NumCast(dragDoc.y) - dropY;
                     de.data.targetContext = this.props.Document; // dropped a PDF annotation, so we need to set the targetContext on the dragData which the PDF view uses at the end of the drop operation
@@ -183,23 +184,23 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     pickCluster(probe: number[]) {
         return this.childLayoutPairs.map(pair => pair.layout).reduce((cluster, cd) => {
-            let layoutDoc = Doc.Layout(cd);
-            let cx = NumCast(cd.x) - this._clusterDistance;
-            let cy = NumCast(cd.y) - this._clusterDistance;
-            let cw = NumCast(layoutDoc.width) + 2 * this._clusterDistance;
-            let ch = NumCast(layoutDoc.height) + 2 * this._clusterDistance;
+            const layoutDoc = Doc.Layout(cd);
+            const cx = NumCast(cd.x) - this._clusterDistance;
+            const cy = NumCast(cd.y) - this._clusterDistance;
+            const cw = NumCast(layoutDoc.width) + 2 * this._clusterDistance;
+            const ch = NumCast(layoutDoc.height) + 2 * this._clusterDistance;
             return !layoutDoc.z && intersectRect({ left: cx, top: cy, width: cw, height: ch }, { left: probe[0], top: probe[1], width: 1, height: 1 }) ?
                 NumCast(cd.cluster) : cluster;
         }, -1);
     }
     tryDragCluster(e: PointerEvent | TouchEvent) {
-        let ptsParent = e instanceof PointerEvent ? e : e.targetTouches.item(0);
+        const ptsParent = e instanceof PointerEvent ? e : e.targetTouches.item(0);
         if (ptsParent) {
-            let cluster = this.pickCluster(this.getTransform().transformPoint(ptsParent.clientX, ptsParent.clientY));
+            const cluster = this.pickCluster(this.getTransform().transformPoint(ptsParent.clientX, ptsParent.clientY));
             if (cluster !== -1) {
-                let eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => NumCast(cd.cluster) === cluster);
-                let clusterDocs = eles.map(ele => DocumentManager.Instance.getDocumentView(ele, this.props.CollectionView)!);
-                let de = new DragManager.DocumentDragData(eles);
+                const eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => NumCast(cd.cluster) === cluster);
+                const clusterDocs = eles.map(ele => DocumentManager.Instance.getDocumentView(ele, this.props.CollectionView)!);
+                const de = new DragManager.DocumentDragData(eles);
                 de.moveDocument = this.props.moveDocument;
                 const [left, top] = clusterDocs[0].props.ScreenToLocalTransform().scale(clusterDocs[0].props.ContentScaling()).inverse().transformPoint(0, 0);
                 de.offset = this.getTransform().transformDirection(ptsParent.clientX - left, ptsParent.clientY - top);
@@ -225,10 +226,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     @undoBatch
     @action
     updateCluster(doc: Doc) {
-        let childLayouts = this.childLayoutPairs.map(pair => pair.layout);
+        const childLayouts = this.childLayoutPairs.map(pair => pair.layout);
         if (this.props.Document.useClusters) {
             this._clusterSets.map(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1));
-            let preferredInd = NumCast(doc.cluster);
+            const preferredInd = NumCast(doc.cluster);
             doc.cluster = -1;
             this._clusterSets.map((set, i) => set.map(member => {
                 if (doc.cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && Doc.overlapping(doc, member, this._clusterDistance)) {
@@ -255,15 +256,15 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     getClusterColor = (doc: Doc) => {
         let clusterColor = "";
-        let cluster = NumCast(doc.cluster);
+        const cluster = NumCast(doc.cluster);
         if (this.Document.useClusters) {
             if (this._clusterSets.length <= cluster) {
                 setTimeout(() => this.updateCluster(doc), 0);
             } else {
                 // choose a cluster color from a palette
-                let colors = ["#da42429e", "#31ea318c", "#8c4000", "#4a7ae2c4", "#d809ff", "#ff7601", "#1dffff", "yellow", "#1b8231f2", "#000000ad"];
+                const colors = ["#da42429e", "#31ea318c", "#8c4000", "#4a7ae2c4", "#d809ff", "#ff7601", "#1dffff", "yellow", "#1b8231f2", "#000000ad"];
                 clusterColor = colors[cluster % colors.length];
-                let set = this._clusterSets[cluster] && this._clusterSets[cluster].filter(s => s.backgroundColor && (s.backgroundColor !== s.defaultBackgroundColor));
+                const set = this._clusterSets[cluster] && this._clusterSets[cluster].filter(s => s.backgroundColor && (s.backgroundColor !== s.defaultBackgroundColor));
                 // override the cluster color with an explicitly set color on a non-background document.  then override that with an explicitly set color on a background document
                 set && set.filter(s => !s.isBackground).map(s => clusterColor = StrCast(s.backgroundColor));
                 set && set.filter(s => s.isBackground).map(s => clusterColor = StrCast(s.backgroundColor));
@@ -287,7 +288,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || (InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen)) {
                 e.stopPropagation();
                 e.preventDefault();
-                let point = this.getTransform().transformPoint(e.pageX, e.pageY);
+                const point = this.getTransform().transformPoint(e.pageX, e.pageY);
                 this._points.push({ x: point[0], y: point[1] });
             }
             // if not using a pen and in no ink mode
@@ -324,7 +325,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     @action
     handle1PointerDown = (e: React.TouchEvent) => {
-        let pt = e.targetTouches.item(0);
+        const pt = e.targetTouches.item(0);
         if (pt) {
             this._hitCluster = this.props.Document.useCluster ? this.pickCluster(this.getTransform().transformPoint(pt.clientX, pt.clientY)) !== -1 : false;
         }
@@ -335,9 +336,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         if (InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE) && this._points.length <= 1) return;
 
         if (this._points.length > 1) {
-            let B = this.svgBounds;
-            let points = this._points.map(p => ({ x: p.x - B.left, y: p.y - B.top }));
-            let inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { width: B.width, height: B.height, x: B.left, y: B.top });
+            const B = this.svgBounds;
+            const points = this._points.map(p => ({ x: p.x - B.left, y: p.y - B.top }));
+            const inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { width: B.width, height: B.height, x: B.left, y: B.top });
             this.addDocument(inkDoc);
             this._points = [];
         }
@@ -355,26 +356,26 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
         let x = this.Document.panX || 0;
         let y = this.Document.panY || 0;
-        let docs = this.childLayoutPairs.map(pair => pair.layout);
-        let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
+        const docs = this.childLayoutPairs.map(pair => pair.layout);
+        const [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
         if (!this.isAnnotationOverlay) {
             PDFMenu.Instance.fadeOut(true);
-            let minx = docs.length ? NumCast(docs[0].x) : 0;
-            let maxx = docs.length ? NumCast(docs[0].width) + minx : minx;
-            let miny = docs.length ? NumCast(docs[0].y) : 0;
-            let maxy = docs.length ? NumCast(docs[0].height) + miny : miny;
-            let ranges = docs.filter(doc => doc).reduce((range, doc) => {
-                let layoutDoc = Doc.Layout(doc);
-                let x = NumCast(doc.x);
-                let xe = x + NumCast(layoutDoc.width);
-                let y = NumCast(doc.y);
-                let ye = y + NumCast(layoutDoc.height);
+            const minx = docs.length ? NumCast(docs[0].x) : 0;
+            const maxx = docs.length ? NumCast(docs[0].width) + minx : minx;
+            const miny = docs.length ? NumCast(docs[0].y) : 0;
+            const maxy = docs.length ? NumCast(docs[0].height) + miny : miny;
+            const ranges = docs.filter(doc => doc).reduce((range, doc) => {
+                const layoutDoc = Doc.Layout(doc);
+                const x = NumCast(doc.x);
+                const xe = x + NumCast(layoutDoc.width);
+                const y = NumCast(doc.y);
+                const ye = y + NumCast(layoutDoc.height);
                 return [[range[0][0] > x ? x : range[0][0], range[0][1] < xe ? xe : range[0][1]],
                 [range[1][0] > y ? y : range[1][0], range[1][1] < ye ? ye : range[1][1]]];
             }, [[minx, maxx], [miny, maxy]]);
 
-            let cscale = this.props.ContainingCollectionDoc ? NumCast(this.props.ContainingCollectionDoc.scale) : 1;
-            let panelDim = this.props.ScreenToLocalTransform().transformDirection(this.props.PanelWidth() / this.zoomScaling() * cscale,
+            const cscale = this.props.ContainingCollectionDoc ? NumCast(this.props.ContainingCollectionDoc.scale) : 1;
+            const panelDim = this.props.ScreenToLocalTransform().transformDirection(this.props.PanelWidth() / this.zoomScaling() * cscale,
                 this.props.PanelHeight() / this.zoomScaling() * cscale);
             if (ranges[0][0] - dx > (this.panX() + panelDim[0] / 2)) x = ranges[0][1] + panelDim[0] / 2;
             if (ranges[0][1] - dx < (this.panX() - panelDim[0] / 2)) x = ranges[0][0] - panelDim[0] / 2;
@@ -397,7 +398,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         if (!e.cancelBubble) {
             const selectedTool = InkingControl.Instance.selectedTool;
             if (selectedTool === InkTool.Highlighter || selectedTool === InkTool.Pen || InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) {
-                let point = this.getTransform().transformPoint(e.clientX, e.clientY);
+                const point = this.getTransform().transformPoint(e.clientX, e.clientY);
                 this._points.push({ x: point[0], y: point[1] });
             }
             else if (selectedTool === InkTool.None) {
@@ -418,7 +419,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     handle1PointerMove = (e: TouchEvent) => {
         // panning a workspace
         if (!e.cancelBubble) {
-            let pt = e.targetTouches.item(0);
+            const pt = e.targetTouches.item(0);
             if (pt) {
                 if (InkingControl.Instance.selectedTool === InkTool.None) {
                     if (this._hitCluster && this.tryDragCluster(e)) {
@@ -431,7 +432,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                     this.pan(pt);
                 }
                 else if (InkingControl.Instance.selectedTool !== InkTool.Eraser && InkingControl.Instance.selectedTool !== InkTool.Scrubber) {
-                    let point = this.getTransform().transformPoint(pt.clientX, pt.clientY);
+                    const point = this.getTransform().transformPoint(pt.clientX, pt.clientY);
                     this._points.push({ x: point[0], y: point[1] });
                 }
             }
@@ -443,28 +444,28 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     handle2PointersMove = (e: TouchEvent) => {
         // pinch zooming
         if (!e.cancelBubble) {
-            let pt1: Touch | null = e.targetTouches.item(0);
-            let pt2: Touch | null = e.targetTouches.item(1);
+            const pt1: Touch | null = e.targetTouches.item(0);
+            const pt2: Touch | null = e.targetTouches.item(1);
             if (!pt1 || !pt2) return;
 
             if (this.prevPoints.size === 2) {
-                let oldPoint1 = this.prevPoints.get(pt1.identifier);
-                let oldPoint2 = this.prevPoints.get(pt2.identifier);
+                const oldPoint1 = this.prevPoints.get(pt1.identifier);
+                const oldPoint2 = this.prevPoints.get(pt2.identifier);
                 if (oldPoint1 && oldPoint2) {
-                    let dir = InteractionUtils.Pinching(pt1, pt2, oldPoint1, oldPoint2);
+                    const dir = InteractionUtils.Pinching(pt1, pt2, oldPoint1, oldPoint2);
 
                     // if zooming, zoom
                     if (dir !== 0) {
-                        let d1 = Math.sqrt(Math.pow(pt1.clientX - oldPoint1.clientX, 2) + Math.pow(pt1.clientY - oldPoint1.clientY, 2));
-                        let d2 = Math.sqrt(Math.pow(pt2.clientX - oldPoint2.clientX, 2) + Math.pow(pt2.clientY - oldPoint2.clientY, 2));
-                        let centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2;
-                        let centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2;
+                        const d1 = Math.sqrt(Math.pow(pt1.clientX - oldPoint1.clientX, 2) + Math.pow(pt1.clientY - oldPoint1.clientY, 2));
+                        const d2 = Math.sqrt(Math.pow(pt2.clientX - oldPoint2.clientX, 2) + Math.pow(pt2.clientY - oldPoint2.clientY, 2));
+                        const centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2;
+                        const centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2;
 
                         // calculate the raw delta value
-                        let rawDelta = (dir * (d1 + d2));
+                        const rawDelta = (dir * (d1 + d2));
 
                         // this floors and ceils the delta value to prevent jitteriness
-                        let delta = Math.sign(rawDelta) * Math.min(Math.abs(rawDelta), 16);
+                        const delta = Math.sign(rawDelta) * Math.min(Math.abs(rawDelta), 16);
                         this.zoom(centerX, centerY, delta);
                         this.prevPoints.set(pt1.identifier, pt1);
                         this.prevPoints.set(pt2.identifier, pt2);
@@ -472,8 +473,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                     // this is not zooming. derive some form of panning from it.
                     else {
                         // use the centerx and centery as the "new mouse position"
-                        let centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2;
-                        let centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2;
+                        const centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2;
+                        const centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2;
                         this.pan({ clientX: centerX, clientY: centerY });
                         this._lastX = centerX;
                         this._lastY = centerY;
@@ -486,12 +487,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
     handle2PointersDown = (e: React.TouchEvent) => {
-        let pt1: React.Touch | null = e.targetTouches.item(0);
-        let pt2: React.Touch | null = e.targetTouches.item(1);
+        const pt1: React.Touch | null = e.targetTouches.item(0);
+        const pt2: React.Touch | null = e.targetTouches.item(1);
         if (!pt1 || !pt2) return;
 
-        let centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2;
-        let centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2;
+        const centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2;
+        const centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2;
         this._lastX = centerX;
         this._lastY = centerY;
     }
@@ -510,11 +511,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             deltaScale = 1 / this.zoomScaling();
         }
         if (deltaScale < 0) deltaScale = -deltaScale;
-        let [x, y] = this.getTransform().transformPoint(pointX, pointY);
-        let localTransform = this.getLocalTransform().inverse().scaleAbout(deltaScale, x, y);
+        const [x, y] = this.getTransform().transformPoint(pointX, pointY);
+        const localTransform = this.getLocalTransform().inverse().scaleAbout(deltaScale, x, y);
 
         if (localTransform.Scale >= 0.15) {
-            let safeScale = Math.min(Math.max(0.15, localTransform.Scale), 40);
+            const safeScale = Math.min(Math.max(0.15, localTransform.Scale), 40);
             this.props.Document.scale = Math.abs(safeScale);
             this.setPan(-localTransform.TranslateX / safeScale, -localTransform.TranslateY / safeScale);
         }
@@ -536,7 +537,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     setPan(panX: number, panY: number, panType: string = "None") {
         if (!this.Document.lockedTransform || this.Document.inOverlay) {
             this.Document.panTransformType = panType;
-            var scale = this.getLocalTransform().inverse().Scale;
+            const scale = this.getLocalTransform().inverse().Scale;
             const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX));
             const newPanY = Math.min((this.props.Document.scrollHeight !== undefined ? NumCast(this.Document.scrollHeight) : (1 - 1 / scale) * this.nativeHeight), Math.max(0, panY));
             this.Document.panX = this.isAnnotationOverlay ? newPanX : panX;
@@ -576,23 +577,23 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         }
         SelectionManager.DeselectAll();
         if (this.props.Document.scrollHeight) {
-            let annotOn = Cast(doc.annotationOn, Doc) as Doc;
+            const annotOn = Cast(doc.annotationOn, Doc) as Doc;
             if (!annotOn) {
                 this.props.focus(doc);
             } else {
-                let contextHgt = Doc.AreProtosEqual(annotOn, this.props.Document) && this.props.VisibleHeight ? this.props.VisibleHeight() : NumCast(annotOn.height);
-                let offset = annotOn && (contextHgt / 2 * 96 / 72);
+                const contextHgt = Doc.AreProtosEqual(annotOn, this.props.Document) && this.props.VisibleHeight ? this.props.VisibleHeight() : NumCast(annotOn.height);
+                const offset = annotOn && (contextHgt / 2 * 96 / 72);
                 this.props.Document.scrollY = NumCast(doc.y) - offset;
             }
         } else {
-            let layoutdoc = Doc.Layout(doc);
+            const layoutdoc = Doc.Layout(doc);
             const newPanX = NumCast(doc.x) + NumCast(layoutdoc.width) / 2;
             const newPanY = NumCast(doc.y) + NumCast(layoutdoc.height) / 2;
             const newState = HistoryUtil.getState();
             newState.initializers![this.Document[Id]] = { panX: newPanX, panY: newPanY };
             HistoryUtil.pushState(newState);
 
-            let savedState = { px: this.Document.panX, py: this.Document.panY, s: this.Document.scale, pt: this.Document.panTransformType };
+            const savedState = { px: this.Document.panX, py: this.Document.panY, s: this.Document.scale, pt: this.Document.panTransformType };
 
             this.setPan(newPanX, newPanY, "Ease");
             Doc.BrushDoc(this.props.Document);
@@ -677,7 +678,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         }
     }
 
-    childDataProvider = computedFn(function childDataProvider(doc: Doc) { return (this as any)._layoutPoolData.get(doc[Id]); }.bind(this));
+    childDataProvider = computedFn(function childDataProvider(this: any, doc: Doc) { return this._layoutPoolData.get(doc[Id]); }.bind(this));
 
     doPivotLayout(poolData: ObservableMap<string, any>) {
         return computePivotLayout(poolData, this.props.Document, this.childDocs,
@@ -685,10 +686,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
     doFreeformLayout(poolData: ObservableMap<string, any>) {
-        let layoutDocs = this.childLayoutPairs.map(pair => pair.layout);
+        const layoutDocs = this.childLayoutPairs.map(pair => pair.layout);
         const initResult = this.Document.arrangeInit && this.Document.arrangeInit.script.run({ docs: layoutDocs, collection: this.Document }, console.log);
         let state = initResult && initResult.success ? initResult.result.scriptState : undefined;
-        let elements = initResult && initResult.success ? this.viewDefsToJSX(initResult.result.views) : [];
+        const elements = initResult && initResult.success ? this.viewDefsToJSX(initResult.result.views) : [];
 
         this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map((pair, i) => {
             const data = poolData.get(pair.layout[Id]);
@@ -737,7 +738,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     layoutDocsInGrid = () => {
         UndoManager.RunInBatch(() => {
             const docs = DocListCast(this.Document[this.props.fieldKey]);
-            let startX = this.Document.panX || 0;
+            const startX = this.Document.panX || 0;
             let x = startX;
             let y = this.Document.panY || 0;
             let i = 0;
@@ -762,8 +763,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         this.Document.isRuleProvider && this.childLayoutPairs.map(pair =>
             // iterate over the children of a displayed document (or if the displayed document is a template, iterate over the children of that template)
             DocListCast(Doc.Layout(pair.layout).data).map(heading => {
-                let headingPair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, heading);
-                let headingLayout = headingPair.layout && (pair.layout.data_ext instanceof Doc) && (pair.layout.data_ext[`Layout[${headingPair.layout[Id]}]`] as Doc) || headingPair.layout;
+                const headingPair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, heading);
+                const headingLayout = headingPair.layout && (pair.layout.data_ext instanceof Doc) && (pair.layout.data_ext[`Layout[${headingPair.layout[Id]}]`] as Doc) || headingPair.layout;
                 if (headingLayout && NumCast(headingLayout.heading) > 0 && headingLayout.backgroundColor !== headingLayout.defaultBackgroundColor) {
                     Doc.GetProto(this.props.Document)["ruleColor_" + NumCast(headingLayout.heading)] = headingLayout.backgroundColor;
                 }
@@ -772,11 +773,23 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
     analyzeStrokes = async () => {
-        //  CognitiveServices.Inking.Appliers.ConcatenateHandwriting(this.dataDoc, ["inkAnalysis", "handwriting"], data.inkData);
+        const children = await DocListCastAsync(this.dataDoc.data);
+        if (!children) {
+            return;
+        }
+        const inkData: InkData[] = [];
+        for (const doc of children) {
+            const data = Cast(doc.data, InkField)?.inkData;
+            data && inkData.push(data);
+        }
+        if (!inkData.length) {
+            return;
+        }
+        CognitiveServices.Inking.Appliers.ConcatenateHandwriting(this.dataDoc, ["inkAnalysis", "handwriting"], inkData);
     }
 
     onContextMenu = (e: React.MouseEvent) => {
-        let layoutItems: ContextMenuProps[] = [];
+        const layoutItems: ContextMenuProps[] = [];
 
         if (this.childDocs.some(d => BoolCast(d.isTemplateDoc))) {
             layoutItems.push({ description: "Template Layout Instance", event: () => this.props.addDocTab(Doc.ApplyTemplate(this.props.Document)!, undefined, "onRight"), icon: "project-diagram" });
@@ -795,7 +808,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                 input.accept = ".zip";
                 input.onchange = async _e => {
                     const upload = Utils.prepend("/uploadDoc");
-                    let formData = new FormData();
+                    const formData = new FormData();
                     const file = input.files && input.files[0];
                     if (file) {
                         formData.append('file', file);
@@ -830,7 +843,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
 
     private childViews = () => {
-        let children = typeof this.props.children === "function" ? (this.props.children as any)() as JSX.Element[] : [];
+        const children = typeof this.props.children === "function" ? (this.props.children as any)() as JSX.Element[] : [];
         return [
             ...children,
             ...this.views,
@@ -838,12 +851,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
     @computed get svgBounds() {
-        let xs = this._points.map(p => p.x);
-        let ys = this._points.map(p => p.y);
-        let right = Math.max(...xs);
-        let left = Math.min(...xs);
-        let bottom = Math.max(...ys);
-        let top = Math.min(...ys);
+        const xs = this._points.map(p => p.x);
+        const ys = this._points.map(p => p.y);
+        const right = Math.max(...xs);
+        const left = Math.min(...xs);
+        const bottom = Math.max(...ys);
+        const top = Math.min(...ys);
         return { right: right, left: left, bottom: bottom, top: top, width: right - left, height: bottom - top };
     }
 
@@ -852,7 +865,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             return (null);
         }
 
-        let B = this.svgBounds;
+        const B = this.svgBounds;
 
         return (
             <svg width={B.width} height={B.height} style={{ transform: `translate(${B.left}px, ${B.top}px)` }}>
@@ -862,7 +875,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
     children = () => {
-        let eles: JSX.Element[] = [];
+        const eles: JSX.Element[] = [];
         this.extensionDoc && (eles.push(...this.childViews()));
         this.currentStroke && (eles.push(this.currentStroke));
         eles.push(<CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />);
@@ -917,7 +930,7 @@ interface CollectionFreeFormViewPannableContentsProps {
 @observer
 class CollectionFreeFormViewPannableContents extends React.Component<CollectionFreeFormViewPannableContentsProps>{
     render() {
-        let freeformclass = "collectionfreeformview" + (this.props.easing() ? "-ease" : "-none");
+        const freeformclass = "collectionfreeformview" + (this.props.easing() ? "-ease" : "-none");
         const cenx = this.props.centeringShiftX();
         const ceny = this.props.centeringShiftY();
         const panx = -this.props.panX();
-- 
cgit v1.2.3-70-g09d2

