From 26e94812b02e178ead5d5be7cfe5bf73e92ac875 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 13 May 2020 20:09:06 -0400
Subject: fixed map view doc references. changed doc view lock icon. made web
 box content @computed

---
 src/client/views/nodes/DocumentView.tsx | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 91275d89b..d821bb8ac 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1165,7 +1165,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             </> :
                 this.innards}
             {(this.Document.isBackground !== undefined || this.isSelected(false)) && this.props.renderDepth > 0 && this.props.PanelWidth() > 0 ?
-                <div className="documentView-lock" onClick={() => this.toggleBackground(true)}> <FontAwesomeIcon icon={this.Document.isBackground ? "unlock" : "lock"} size="lg" /> </div>
+                <div className="documentView-lock" onClick={() => this.toggleBackground(true)}>
+                    <FontAwesomeIcon icon={this.Document.isBackground ? "unlock" : "lock"} style={{ color: this.Document.isBackground ? "red" : undefined }} size="lg" />
+                </div>
                 : (null)}
         </div>;
         { this._showKPQuery ? <KeyphraseQueryView keyphrases={this._queries}></KeyphraseQueryView> : undefined; }
-- 
cgit v1.2.3-70-g09d2


From 2b79008596351f6948d8de80c7887446d97b068c Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Fri, 15 May 2020 00:03:41 -0700
Subject: renamed new_fields to fields

---
 src/client/ClientRecommender.tsx                   |   16 +-
 src/client/DocServer.ts                            |    6 +-
 src/client/apis/GoogleAuthenticationManager.tsx    |    2 +-
 src/client/apis/IBM_Recommender.ts                 |    2 +-
 .../apis/google_docs/GoogleApiClientUtils.ts       |    2 +-
 .../apis/google_docs/GooglePhotosClientUtils.ts    |   12 +-
 src/client/apis/youtube/YoutubeBox.tsx             |    4 +-
 src/client/cognitive_services/CognitiveServices.ts |    8 +-
 src/client/documents/Documents.ts                  |   22 +-
 src/client/util/CurrentUserUtils.ts                |   18 +-
 src/client/util/DictationManager.ts                |   12 +-
 src/client/util/DocumentManager.ts                 |    6 +-
 src/client/util/DragManager.ts                     |   16 +-
 src/client/util/DropConverter.ts                   |   12 +-
 src/client/util/History.ts                         |    2 +-
 .../util/Import & Export/DirectoryImportBox.tsx    |   12 +-
 src/client/util/Import & Export/ImageUtils.ts      |    8 +-
 .../util/Import & Export/ImportMetadataEntry.tsx   |    4 +-
 src/client/util/LinkManager.ts                     |    8 +-
 src/client/util/Scripting.ts                       |    2 +-
 src/client/util/SearchUtil.ts                      |    4 +-
 src/client/util/SelectionManager.ts                |    4 +-
 src/client/util/SerializationHelper.ts             |    2 +-
 src/client/util/SharingManager.tsx                 |    6 +-
 src/client/views/DocComponent.tsx                  |   14 +-
 src/client/views/DocumentButtonBar.tsx             |    6 +-
 src/client/views/DocumentDecorations.tsx           |   24 +-
 src/client/views/EditableView.tsx                  |    4 +-
 src/client/views/GestureOverlay.tsx                |   12 +-
 src/client/views/GlobalKeyHandler.ts               |   14 +-
 src/client/views/InkingControl.tsx                 |    6 +-
 src/client/views/InkingStroke.tsx                  |   10 +-
 src/client/views/MainView.tsx                      |   14 +-
 src/client/views/MainViewNotifs.tsx                |    2 +-
 src/client/views/MetadataEntryMenu.tsx             |    2 +-
 src/client/views/OverlayView.tsx                   |    6 +-
 src/client/views/Palette.tsx                       |    4 +-
 src/client/views/PreviewCursor.tsx                 |    4 +-
 src/client/views/RecommendationsBox.tsx            |    8 +-
 src/client/views/ScriptBox.tsx                     |    6 +-
 src/client/views/SearchDocBox.tsx                  |    6 +-
 src/client/views/TemplateMenu.tsx                  |    8 +-
 src/client/views/animationtimeline/Keyframe.tsx    |    8 +-
 src/client/views/animationtimeline/Timeline.tsx    |    8 +-
 src/client/views/animationtimeline/Track.tsx       |   12 +-
 .../views/collections/CollectionCarouselView.tsx   |   10 +-
 .../views/collections/CollectionDockingView.tsx    |   29 +-
 .../views/collections/CollectionLinearView.tsx     |   10 +-
 src/client/views/collections/CollectionMapView.tsx |   10 +-
 .../collections/CollectionMasonryViewFieldRow.tsx  |    8 +-
 .../views/collections/CollectionPileView.tsx       |    6 +-
 .../views/collections/CollectionSchemaCells.tsx    |    8 +-
 .../views/collections/CollectionSchemaHeaders.tsx  |    2 +-
 .../CollectionSchemaMovableTableHOC.tsx            |    6 +-
 .../views/collections/CollectionSchemaView.tsx     |   14 +-
 .../views/collections/CollectionStackingView.tsx   |   16 +-
 .../CollectionStackingViewFieldColumn.tsx          |   16 +-
 .../views/collections/CollectionStaffView.tsx      |    2 +-
 src/client/views/collections/CollectionSubView.tsx |   14 +-
 .../views/collections/CollectionTimeView.tsx       |   12 +-
 .../views/collections/CollectionTreeView.tsx       |   16 +-
 src/client/views/collections/CollectionView.tsx    |   20 +-
 .../views/collections/CollectionViewChromes.tsx    |   10 +-
 .../views/collections/ParentDocumentSelector.tsx   |    6 +-
 .../CollectionFreeFormLayoutEngines.tsx            |   14 +-
 .../CollectionFreeFormLinkView.tsx                 |    6 +-
 .../CollectionFreeFormLinksView.tsx                |    4 +-
 .../CollectionFreeFormRemoteCursors.tsx            |   10 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   23 +-
 .../collections/collectionFreeForm/MarqueeView.tsx |   12 +-
 .../CollectionMulticolumnView.tsx                  |   10 +-
 .../CollectionMultirowView.tsx                     |   10 +-
 .../collectionMulticolumn/MulticolumnResizer.tsx   |    4 +-
 .../MulticolumnWidthLabel.tsx                      |    4 +-
 .../collectionMulticolumn/MultirowHeightLabel.tsx  |    4 +-
 .../collectionMulticolumn/MultirowResizer.tsx      |    4 +-
 src/client/views/linking/LinkEditor.tsx            |    4 +-
 src/client/views/linking/LinkMenu.tsx              |    2 +-
 src/client/views/linking/LinkMenuGroup.tsx         |    6 +-
 src/client/views/linking/LinkMenuItem.tsx          |    4 +-
 src/client/views/nodes/AudioBox.tsx                |   16 +-
 .../views/nodes/CollectionFreeFormDocumentView.tsx |    8 +-
 src/client/views/nodes/ColorBox.tsx                |    6 +-
 .../views/nodes/ContentFittingDocumentView.tsx     |    6 +-
 src/client/views/nodes/DocHolderBox.tsx            |   12 +-
 src/client/views/nodes/DocumentContentsView.tsx    |    8 +-
 src/client/views/nodes/DocumentIcon.tsx            |    2 +-
 src/client/views/nodes/DocumentView.tsx            |   20 +-
 src/client/views/nodes/FaceRectangles.tsx          |    6 +-
 src/client/views/nodes/FieldView.tsx               |   10 +-
 src/client/views/nodes/FontIconBox.tsx             |    8 +-
 src/client/views/nodes/ImageBox.tsx                |   20 +-
 src/client/views/nodes/KeyValueBox.tsx             |   14 +-
 src/client/views/nodes/KeyValuePair.tsx            |    2 +-
 src/client/views/nodes/LabelBox.tsx                |   10 +-
 src/client/views/nodes/LinkAnchorBox.tsx           |   10 +-
 src/client/views/nodes/LinkBox.tsx                 |    6 +-
 src/client/views/nodes/PDFBox.tsx                  |   12 +-
 src/client/views/nodes/PresBox.tsx                 |   16 +-
 src/client/views/nodes/QueryBox.tsx                |   10 +-
 src/client/views/nodes/ScreenshotBox.tsx           |    8 +-
 src/client/views/nodes/ScriptingBox.tsx            |   10 +-
 src/client/views/nodes/SliderBox.tsx               |    8 +-
 src/client/views/nodes/VideoBox.tsx                |   16 +-
 src/client/views/nodes/WebBox.tsx                  |   14 +-
 .../nodes/formattedText/DashDocCommentView.tsx     |   16 +-
 .../views/nodes/formattedText/DashDocView.tsx      |   10 +-
 .../views/nodes/formattedText/DashFieldView.tsx    |   12 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |   24 +-
 .../formattedText/FormattedTextBoxComment.tsx      |    4 +-
 .../views/nodes/formattedText/ImageResizeView.tsx  |    2 +-
 .../formattedText/ProsemirrorExampleTransfer.ts    |    6 +-
 .../views/nodes/formattedText/RichTextMenu.tsx     |    6 +-
 .../views/nodes/formattedText/RichTextRules.ts     |   10 +-
 .../views/nodes/formattedText/RichTextSchema.tsx   |   16 +-
 src/client/views/nodes/formattedText/marks_rts.ts  |    2 +-
 src/client/views/pdf/Annotation.tsx                |    8 +-
 src/client/views/pdf/PDFMenu.tsx                   |    2 +-
 src/client/views/pdf/PDFViewer.tsx                 |   20 +-
 .../views/presentationview/PresElementBox.tsx      |   10 +-
 src/client/views/search/FilterBox.tsx              |    6 +-
 src/client/views/search/SearchBox.tsx              |    8 +-
 src/client/views/search/SearchItem.tsx             |    6 +-
 src/debug/Repl.tsx                                 |    6 +-
 src/debug/Test.tsx                                 |    2 +-
 src/debug/Viewer.tsx                               |   16 +-
 src/fields/CursorField.ts                          |   66 ++
 src/fields/DateField.ts                            |   36 +
 src/fields/Doc.ts                                  | 1109 ++++++++++++++++++++
 src/fields/FieldSymbols.ts                         |   12 +
 src/fields/HtmlField.ts                            |   26 +
 src/fields/IconField.ts                            |   26 +
 src/fields/InkField.ts                             |   50 +
 src/fields/List.ts                                 |  330 ++++++
 src/fields/ListSpec.ts                             |    0
 src/fields/ObjectField.ts                          |   20 +
 src/fields/PresField.ts                            |    6 +
 src/fields/Proxy.ts                                |  126 +++
 src/fields/RefField.ts                             |   21 +
 src/fields/RichTextField.ts                        |   41 +
 src/fields/RichTextUtils.ts                        |  519 +++++++++
 src/fields/Schema.ts                               |  120 +++
 src/fields/SchemaHeaderField.ts                    |  122 +++
 src/fields/ScriptField.ts                          |  193 ++++
 src/fields/Types.ts                                |  108 ++
 src/fields/URLField.ts                             |   53 +
 src/fields/documentSchemas.ts                      |  100 ++
 src/fields/util.ts                                 |  199 ++++
 src/mobile/ImageUpload.tsx                         |    8 +-
 src/mobile/MobileInkOverlay.tsx                    |    6 +-
 src/mobile/MobileInterface.tsx                     |   12 +-
 src/new_fields/CursorField.ts                      |   66 --
 src/new_fields/DateField.ts                        |   36 -
 src/new_fields/Doc.ts                              | 1109 --------------------
 src/new_fields/FieldSymbols.ts                     |   12 -
 src/new_fields/HtmlField.ts                        |   26 -
 src/new_fields/IconField.ts                        |   26 -
 src/new_fields/InkField.ts                         |   50 -
 src/new_fields/List.ts                             |  330 ------
 src/new_fields/ListSpec.ts                         |    0
 src/new_fields/ObjectField.ts                      |   20 -
 src/new_fields/PresField.ts                        |    6 -
 src/new_fields/Proxy.ts                            |  126 ---
 src/new_fields/RefField.ts                         |   21 -
 src/new_fields/RichTextField.ts                    |   41 -
 src/new_fields/RichTextUtils.ts                    |  519 ---------
 src/new_fields/Schema.ts                           |  120 ---
 src/new_fields/SchemaHeaderField.ts                |  122 ---
 src/new_fields/ScriptField.ts                      |  193 ----
 src/new_fields/Types.ts                            |  108 --
 src/new_fields/URLField.ts                         |   53 -
 src/new_fields/documentSchemas.ts                  |  100 --
 src/new_fields/util.ts                             |  199 ----
 src/pen-gestures/GestureUtils.ts                   |    6 +-
 src/server/ApiManagers/GooglePhotosManager.ts      |    2 +-
 src/server/ApiManagers/UserManager.ts              |    2 +-
 src/server/DashUploadUtils.ts                      |    2 +-
 src/server/Message.ts                              |    2 +-
 src/server/Recommender.ts                          |    6 +-
 src/server/apis/google/GoogleApiServerUtils.ts     |    2 +-
 src/server/database.ts                             |    2 +-
 test/test.ts                                       |    8 +-
 182 files changed, 3889 insertions(+), 3889 deletions(-)
 create mode 100644 src/fields/CursorField.ts
 create mode 100644 src/fields/DateField.ts
 create mode 100644 src/fields/Doc.ts
 create mode 100644 src/fields/FieldSymbols.ts
 create mode 100644 src/fields/HtmlField.ts
 create mode 100644 src/fields/IconField.ts
 create mode 100644 src/fields/InkField.ts
 create mode 100644 src/fields/List.ts
 create mode 100644 src/fields/ListSpec.ts
 create mode 100644 src/fields/ObjectField.ts
 create mode 100644 src/fields/PresField.ts
 create mode 100644 src/fields/Proxy.ts
 create mode 100644 src/fields/RefField.ts
 create mode 100644 src/fields/RichTextField.ts
 create mode 100644 src/fields/RichTextUtils.ts
 create mode 100644 src/fields/Schema.ts
 create mode 100644 src/fields/SchemaHeaderField.ts
 create mode 100644 src/fields/ScriptField.ts
 create mode 100644 src/fields/Types.ts
 create mode 100644 src/fields/URLField.ts
 create mode 100644 src/fields/documentSchemas.ts
 create mode 100644 src/fields/util.ts
 delete mode 100644 src/new_fields/CursorField.ts
 delete mode 100644 src/new_fields/DateField.ts
 delete mode 100644 src/new_fields/Doc.ts
 delete mode 100644 src/new_fields/FieldSymbols.ts
 delete mode 100644 src/new_fields/HtmlField.ts
 delete mode 100644 src/new_fields/IconField.ts
 delete mode 100644 src/new_fields/InkField.ts
 delete mode 100644 src/new_fields/List.ts
 delete mode 100644 src/new_fields/ListSpec.ts
 delete mode 100644 src/new_fields/ObjectField.ts
 delete mode 100644 src/new_fields/PresField.ts
 delete mode 100644 src/new_fields/Proxy.ts
 delete mode 100644 src/new_fields/RefField.ts
 delete mode 100644 src/new_fields/RichTextField.ts
 delete mode 100644 src/new_fields/RichTextUtils.ts
 delete mode 100644 src/new_fields/Schema.ts
 delete mode 100644 src/new_fields/SchemaHeaderField.ts
 delete mode 100644 src/new_fields/ScriptField.ts
 delete mode 100644 src/new_fields/Types.ts
 delete mode 100644 src/new_fields/URLField.ts
 delete mode 100644 src/new_fields/documentSchemas.ts
 delete mode 100644 src/new_fields/util.ts

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/ClientRecommender.tsx b/src/client/ClientRecommender.tsx
index 537e331ab..d18669b02 100644
--- a/src/client/ClientRecommender.tsx
+++ b/src/client/ClientRecommender.tsx
@@ -1,6 +1,6 @@
-import { Doc, FieldResult } from "../new_fields/Doc";
-import { StrCast, Cast } from "../new_fields/Types";
-import { List } from "../new_fields/List";
+import { Doc, FieldResult } from "../fields/Doc";
+import { StrCast, Cast } from "../fields/Types";
+import { List } from "../fields/List";
 import { CognitiveServices, Confidence, Tag, Service } from "./cognitive_services/CognitiveServices";
 import React = require("react");
 import { observer } from "mobx-react";
@@ -11,11 +11,11 @@ import { observable, action, computed, reaction } from "mobx";
 // var https = require('https');
 import "./ClientRecommender.scss";
 import { JSXElement } from "babel-types";
-import { RichTextField } from "../new_fields/RichTextField";
-import { ToPlainText } from "../new_fields/FieldSymbols";
-import { listSpec } from "../new_fields/Schema";
-import { ComputedField } from "../new_fields/ScriptField";
-import { ImageField } from "../new_fields/URLField";
+import { RichTextField } from "../fields/RichTextField";
+import { ToPlainText } from "../fields/FieldSymbols";
+import { listSpec } from "../fields/Schema";
+import { ComputedField } from "../fields/ScriptField";
+import { ImageField } from "../fields/URLField";
 import { KeyphraseQueryView } from "./views/KeyphraseQueryView";
 import { Networking } from "./Network";
 
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index ae125694b..ac5b7a218 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -1,10 +1,10 @@
 import * as OpenSocket from 'socket.io-client';
 import { MessageStore, YoutubeQueryTypes, GestureContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, MobileDocumentUploadContent } from "./../server/Message";
-import { Opt, Doc } from '../new_fields/Doc';
+import { Opt, Doc } from '../fields/Doc';
 import { Utils, emptyFunction } from '../Utils';
 import { SerializationHelper } from './util/SerializationHelper';
-import { RefField } from '../new_fields/RefField';
-import { Id, HandleUpdate } from '../new_fields/FieldSymbols';
+import { RefField } from '../fields/RefField';
+import { Id, HandleUpdate } from '../fields/FieldSymbols';
 import GestureOverlay from './views/GestureOverlay';
 import MobileInkOverlay from '../mobile/MobileInkOverlay';
 import { runInAction } from 'mobx';
diff --git a/src/client/apis/GoogleAuthenticationManager.tsx b/src/client/apis/GoogleAuthenticationManager.tsx
index 22d6fb582..bf4469aeb 100644
--- a/src/client/apis/GoogleAuthenticationManager.tsx
+++ b/src/client/apis/GoogleAuthenticationManager.tsx
@@ -2,7 +2,7 @@ import { observable, action, reaction, runInAction, IReactionDisposer } from "mo
 import { observer } from "mobx-react";
 import * as React from "react";
 import MainViewModal from "../views/MainViewModal";
-import { Opt } from "../../new_fields/Doc";
+import { Opt } from "../../fields/Doc";
 import { Networking } from "../Network";
 import "./GoogleAuthenticationManager.scss";
 import { Scripting } from "../util/Scripting";
diff --git a/src/client/apis/IBM_Recommender.ts b/src/client/apis/IBM_Recommender.ts
index 4e1c541c8..480b9cb1c 100644
--- a/src/client/apis/IBM_Recommender.ts
+++ b/src/client/apis/IBM_Recommender.ts
@@ -1,4 +1,4 @@
-// import { Opt } from "../../new_fields/Doc";
+// import { Opt } from "../../fields/Doc";
 
 // const NaturalLanguageUnderstandingV1 = require('ibm-watson/natural-language-understanding/v1');
 // const { IamAuthenticator } = require('ibm-watson/auth');
diff --git a/src/client/apis/google_docs/GoogleApiClientUtils.ts b/src/client/apis/google_docs/GoogleApiClientUtils.ts
index 2f3cac8d3..551dca073 100644
--- a/src/client/apis/google_docs/GoogleApiClientUtils.ts
+++ b/src/client/apis/google_docs/GoogleApiClientUtils.ts
@@ -1,5 +1,5 @@
 import { docs_v1 } from "googleapis";
-import { Opt } from "../../../new_fields/Doc";
+import { Opt } from "../../../fields/Doc";
 import { isArray } from "util";
 import { EditorState } from "prosemirror-state";
 import { Networking } from "../../Network";
diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
index 1e4c120bc..fef71ffeb 100644
--- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts
+++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
@@ -1,11 +1,11 @@
 import { AssertionError } from "assert";
 import { EditorState } from "prosemirror-state";
-import { Doc, DocListCastAsync, Opt } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { RichTextField } from "../../../new_fields/RichTextField";
-import { RichTextUtils } from "../../../new_fields/RichTextUtils";
-import { Cast, StrCast } from "../../../new_fields/Types";
-import { ImageField } from "../../../new_fields/URLField";
+import { Doc, DocListCastAsync, Opt } from "../../../fields/Doc";
+import { Id } from "../../../fields/FieldSymbols";
+import { RichTextField } from "../../../fields/RichTextField";
+import { RichTextUtils } from "../../../fields/RichTextUtils";
+import { Cast, StrCast } from "../../../fields/Types";
+import { ImageField } from "../../../fields/URLField";
 import { MediaItem, NewMediaItemResult } from "../../../server/apis/google/SharedTypes";
 import { Utils } from "../../../Utils";
 import { Docs, DocumentOptions } from "../../documents/Documents";
diff --git a/src/client/apis/youtube/YoutubeBox.tsx b/src/client/apis/youtube/YoutubeBox.tsx
index 1575e53fc..ce7f49e64 100644
--- a/src/client/apis/youtube/YoutubeBox.tsx
+++ b/src/client/apis/youtube/YoutubeBox.tsx
@@ -1,7 +1,7 @@
 import { action, observable, runInAction } from 'mobx';
 import { observer } from "mobx-react";
-import { Doc, DocListCastAsync } from "../../../new_fields/Doc";
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Doc, DocListCastAsync } from "../../../fields/Doc";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
 import { Utils } from "../../../Utils";
 import { DocServer } from "../../DocServer";
 import { Docs } from "../../documents/Documents";
diff --git a/src/client/cognitive_services/CognitiveServices.ts b/src/client/cognitive_services/CognitiveServices.ts
index 8c63ae906..d4df7ce57 100644
--- a/src/client/cognitive_services/CognitiveServices.ts
+++ b/src/client/cognitive_services/CognitiveServices.ts
@@ -1,12 +1,12 @@
 import * as request from "request-promise";
-import { Doc, Field } from "../../new_fields/Doc";
-import { Cast } from "../../new_fields/Types";
+import { Doc, Field } from "../../fields/Doc";
+import { Cast } from "../../fields/Types";
 import { Docs } from "../documents/Documents";
 import { Utils } from "../../Utils";
-import { InkData } from "../../new_fields/InkField";
+import { InkData } from "../../fields/InkField";
 import { UndoManager } from "../util/UndoManager";
 import requestPromise = require("request-promise");
-import { List } from "../../new_fields/List";
+import { List } from "../../fields/List";
 import { ClientRecommender } from "../ClientRecommender";
 
 type APIManager<D> = { converter: BodyConverter<D>, requester: RequestExecutor };
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 125a531f4..13687e4e8 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -9,14 +9,14 @@ import { ScriptingBox } from "../views/nodes/ScriptingBox";
 import { VideoBox } from "../views/nodes/VideoBox";
 import { WebBox } from "../views/nodes/WebBox";
 import { OmitKeys, JSONUtils, Utils } from "../../Utils";
-import { Field, Doc, Opt, DocListCastAsync, FieldResult, DocListCast } from "../../new_fields/Doc";
-import { ImageField, VideoField, AudioField, PdfField, WebField, YoutubeField } from "../../new_fields/URLField";
-import { HtmlField } from "../../new_fields/HtmlField";
-import { List } from "../../new_fields/List";
-import { Cast, NumCast, StrCast } from "../../new_fields/Types";
+import { Field, Doc, Opt, DocListCastAsync, FieldResult, DocListCast } from "../../fields/Doc";
+import { ImageField, VideoField, AudioField, PdfField, WebField, YoutubeField } from "../../fields/URLField";
+import { HtmlField } from "../../fields/HtmlField";
+import { List } from "../../fields/List";
+import { Cast, NumCast, StrCast } from "../../fields/Types";
 import { DocServer } from "../DocServer";
 import { dropActionType } from "../util/DragManager";
-import { DateField } from "../../new_fields/DateField";
+import { DateField } from "../../fields/DateField";
 import { YoutubeBox } from "../apis/youtube/YoutubeBox";
 import { CollectionDockingView } from "../views/collections/CollectionDockingView";
 import { LinkManager } from "../util/LinkManager";
@@ -26,10 +26,10 @@ import { Scripting } from "../util/Scripting";
 import { LabelBox } from "../views/nodes/LabelBox";
 import { SliderBox } from "../views/nodes/SliderBox";
 import { FontIconBox } from "../views/nodes/FontIconBox";
-import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField } from "../../fields/SchemaHeaderField";
 import { PresBox } from "../views/nodes/PresBox";
-import { ComputedField, ScriptField } from "../../new_fields/ScriptField";
-import { ProxyField } from "../../new_fields/Proxy";
+import { ComputedField, ScriptField } from "../../fields/ScriptField";
+import { ProxyField } from "../../fields/Proxy";
 import { DocumentType } from "./DocumentTypes";
 import { RecommendationsBox } from "../views/RecommendationsBox";
 import { PresElementBox } from "../views/presentationview/PresElementBox";
@@ -39,9 +39,9 @@ import { ColorBox } from "../views/nodes/ColorBox";
 import { LinkAnchorBox } from "../views/nodes/LinkAnchorBox";
 import { DocHolderBox } from "../views/nodes/DocHolderBox";
 import { InkingStroke } from "../views/InkingStroke";
-import { InkField } from "../../new_fields/InkField";
+import { InkField } from "../../fields/InkField";
 import { InkingControl } from "../views/InkingControl";
-import { RichTextField } from "../../new_fields/RichTextField";
+import { RichTextField } from "../../fields/RichTextField";
 import { extname } from "path";
 import { MessageStore } from "../../server/Message";
 import { ContextMenuProps } from "../views/ContextMenuItem";
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index b67c3ea60..d9faed36d 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -4,23 +4,23 @@ import { Utils } from "../../Utils";
 import { DocServer } from "../DocServer";
 import { Docs, DocumentOptions } from "../documents/Documents";
 import { UndoManager } from "./UndoManager";
-import { Doc, DocListCast, DocListCastAsync } from "../../new_fields/Doc";
-import { List } from "../../new_fields/List";
-import { listSpec } from "../../new_fields/Schema";
-import { ScriptField, ComputedField } from "../../new_fields/ScriptField";
-import { Cast, PromiseValue, StrCast, NumCast } from "../../new_fields/Types";
-import { nullAudio } from "../../new_fields/URLField";
+import { Doc, DocListCast, DocListCastAsync } from "../../fields/Doc";
+import { List } from "../../fields/List";
+import { listSpec } from "../../fields/Schema";
+import { ScriptField, ComputedField } from "../../fields/ScriptField";
+import { Cast, PromiseValue, StrCast, NumCast } from "../../fields/Types";
+import { nullAudio } from "../../fields/URLField";
 import { DragManager } from "./DragManager";
 import { InkingControl } from "../views/InkingControl";
 import { Scripting } from "./Scripting";
 import { CollectionViewType } from "../views/collections/CollectionView";
 import { makeTemplate } from "./DropConverter";
-import { RichTextField } from "../../new_fields/RichTextField";
-import { PrefetchProxy } from "../../new_fields/Proxy";
+import { RichTextField } from "../../fields/RichTextField";
+import { PrefetchProxy } from "../../fields/Proxy";
 import { FormattedTextBox } from "../views/nodes/formattedText/FormattedTextBox";
 import { MainView } from "../views/MainView";
 import { DocumentType } from "../documents/DocumentTypes";
-import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField } from "../../fields/SchemaHeaderField";
 import { DimUnit } from "../views/collections/collectionMulticolumn/CollectionMulticolumnView";
 
 export class CurrentUserUtils {
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts
index b3295ece0..e46225b4a 100644
--- a/src/client/util/DictationManager.ts
+++ b/src/client/util/DictationManager.ts
@@ -3,15 +3,15 @@ import { DocumentView } from "../views/nodes/DocumentView";
 import { UndoManager } from "./UndoManager";
 import * as interpreter from "words-to-numbers";
 import { DocumentType } from "../documents/DocumentTypes";
-import { Doc, Opt } from "../../new_fields/Doc";
-import { List } from "../../new_fields/List";
+import { Doc, Opt } from "../../fields/Doc";
+import { List } from "../../fields/List";
 import { Docs } from "../documents/Documents";
 import { CollectionViewType } from "../views/collections/CollectionView";
-import { Cast, CastCtor } from "../../new_fields/Types";
-import { listSpec } from "../../new_fields/Schema";
-import { AudioField, ImageField } from "../../new_fields/URLField";
+import { Cast, CastCtor } from "../../fields/Types";
+import { listSpec } from "../../fields/Schema";
+import { AudioField, ImageField } from "../../fields/URLField";
 import { Utils } from "../../Utils";
-import { RichTextField } from "../../new_fields/RichTextField";
+import { RichTextField } from "../../fields/RichTextField";
 import { DictationOverlay } from "../views/DictationOverlay";
 
 /**
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 99d85125a..ab087335e 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -1,7 +1,7 @@
 import { action, computed, observable } from 'mobx';
-import { Doc, DocListCastAsync, DocListCast, Opt } from '../../new_fields/Doc';
-import { Id } from '../../new_fields/FieldSymbols';
-import { Cast, NumCast, StrCast } from '../../new_fields/Types';
+import { Doc, DocListCastAsync, DocListCast, Opt } from '../../fields/Doc';
+import { Id } from '../../fields/FieldSymbols';
+import { Cast, NumCast, StrCast } from '../../fields/Types';
 import { CollectionDockingView } from '../views/collections/CollectionDockingView';
 import { CollectionView } from '../views/collections/CollectionView';
 import { DocumentView, DocFocusFunc } from '../views/nodes/DocumentView';
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index d1d7f2a8a..66c7ecf7d 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,12 +1,12 @@
 import { action, observable, runInAction } from "mobx";
-import { DateField } from "../../new_fields/DateField";
-import { Doc, Field, Opt } from "../../new_fields/Doc";
-import { List } from "../../new_fields/List";
-import { PrefetchProxy } from "../../new_fields/Proxy";
-import { listSpec } from "../../new_fields/Schema";
-import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField";
-import { ScriptField } from "../../new_fields/ScriptField";
-import { Cast, NumCast, ScriptCast, StrCast } from "../../new_fields/Types";
+import { DateField } from "../../fields/DateField";
+import { Doc, Field, Opt } from "../../fields/Doc";
+import { List } from "../../fields/List";
+import { PrefetchProxy } from "../../fields/Proxy";
+import { listSpec } from "../../fields/Schema";
+import { SchemaHeaderField } from "../../fields/SchemaHeaderField";
+import { ScriptField } from "../../fields/ScriptField";
+import { Cast, NumCast, ScriptCast, StrCast } from "../../fields/Types";
 import { emptyFunction } from "../../Utils";
 import { Docs, DocUtils } from "../documents/Documents";
 import * as globalCssVariables from "../views/globalCssVariables.scss";
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index d6db882b8..752c1cfc5 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -1,12 +1,12 @@
 import { DragManager } from "./DragManager";
-import { Doc, DocListCast, Opt } from "../../new_fields/Doc";
+import { Doc, DocListCast, Opt } from "../../fields/Doc";
 import { DocumentType } from "../documents/DocumentTypes";
-import { ObjectField } from "../../new_fields/ObjectField";
-import { StrCast } from "../../new_fields/Types";
+import { ObjectField } from "../../fields/ObjectField";
+import { StrCast } from "../../fields/Types";
 import { Docs } from "../documents/Documents";
-import { ScriptField, ComputedField } from "../../new_fields/ScriptField";
-import { RichTextField } from "../../new_fields/RichTextField";
-import { ImageField } from "../../new_fields/URLField";
+import { ScriptField, ComputedField } from "../../fields/ScriptField";
+import { RichTextField } from "../../fields/RichTextField";
+import { ImageField } from "../../fields/URLField";
 import { Scripting } from "./Scripting";
 
 // 
diff --git a/src/client/util/History.ts b/src/client/util/History.ts
index 2c53d7e52..7b7d4b835 100644
--- a/src/client/util/History.ts
+++ b/src/client/util/History.ts
@@ -1,4 +1,4 @@
-import { Doc } from "../../new_fields/Doc";
+import { Doc } from "../../fields/Doc";
 import { DocServer } from "../DocServer";
 import { MainView } from "../views/MainView";
 import * as qs from 'query-string';
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index 438904688..1e8f07049 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx	
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx	
@@ -1,6 +1,6 @@
 import "fs";
 import React = require("react");
-import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../new_fields/Doc";
+import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../fields/Doc";
 import { action, observable, runInAction, computed, reaction, IReactionDisposer } from "mobx";
 import { FieldViewProps, FieldView } from "../../views/nodes/FieldView";
 import Measure, { ContentRect } from "react-measure";
@@ -12,12 +12,12 @@ import { observer } from "mobx-react";
 import ImportMetadataEntry, { keyPlaceholder, valuePlaceholder } from "./ImportMetadataEntry";
 import { Utils } from "../../../Utils";
 import { DocumentManager } from "../DocumentManager";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { List } from "../../../new_fields/List";
-import { Cast, BoolCast, NumCast } from "../../../new_fields/Types";
-import { listSpec } from "../../../new_fields/Schema";
+import { Id } from "../../../fields/FieldSymbols";
+import { List } from "../../../fields/List";
+import { Cast, BoolCast, NumCast } from "../../../fields/Types";
+import { listSpec } from "../../../fields/Schema";
 import { GooglePhotos } from "../../apis/google_docs/GooglePhotosClientUtils";
-import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
 import "./DirectoryImportBox.scss";
 import { Networking } from "../../Network";
 import { BatchedArray } from "array-batcher";
diff --git a/src/client/util/Import & Export/ImageUtils.ts b/src/client/util/Import & Export/ImageUtils.ts
index c8d1530b3..072e5f58a 100644
--- a/src/client/util/Import & Export/ImageUtils.ts	
+++ b/src/client/util/Import & Export/ImageUtils.ts	
@@ -1,9 +1,9 @@
-import { Doc } from "../../../new_fields/Doc";
-import { ImageField } from "../../../new_fields/URLField";
-import { Cast, StrCast } from "../../../new_fields/Types";
+import { Doc } from "../../../fields/Doc";
+import { ImageField } from "../../../fields/URLField";
+import { Cast, StrCast } from "../../../fields/Types";
 import { Docs } from "../../documents/Documents";
 import { Networking } from "../../Network";
-import { Id } from "../../../new_fields/FieldSymbols";
+import { Id } from "../../../fields/FieldSymbols";
 import { Utils } from "../../../Utils";
 
 export namespace ImageUtils {
diff --git a/src/client/util/Import & Export/ImportMetadataEntry.tsx b/src/client/util/Import & Export/ImportMetadataEntry.tsx
index 8e1c50bea..dcb94e2e0 100644
--- a/src/client/util/Import & Export/ImportMetadataEntry.tsx	
+++ b/src/client/util/Import & Export/ImportMetadataEntry.tsx	
@@ -5,8 +5,8 @@ import { action, computed } from "mobx";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { faPlus } from "@fortawesome/free-solid-svg-icons";
 import { library } from '@fortawesome/fontawesome-svg-core';
-import { Doc } from "../../../new_fields/Doc";
-import { StrCast, BoolCast } from "../../../new_fields/Types";
+import { Doc } from "../../../fields/Doc";
+import { StrCast, BoolCast } from "../../../fields/Types";
 
 interface KeyValueProps {
     Document: Doc;
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index e236c7f47..8e6ccf098 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -1,7 +1,7 @@
-import { Doc, DocListCast } from "../../new_fields/Doc";
-import { List } from "../../new_fields/List";
-import { listSpec } from "../../new_fields/Schema";
-import { Cast, StrCast } from "../../new_fields/Types";
+import { Doc, DocListCast } from "../../fields/Doc";
+import { List } from "../../fields/List";
+import { listSpec } from "../../fields/Schema";
+import { Cast, StrCast } from "../../fields/Types";
 import { Docs } from "../documents/Documents";
 import { Scripting } from "./Scripting";
 
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index 8b7b9c9c7..ab577315c 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -9,7 +9,7 @@ export { ts };
 
 // @ts-ignore
 import * as typescriptlib from '!!raw-loader!./type_decls.d';
-import { Doc, Field } from '../../new_fields/Doc';
+import { Doc, Field } from '../../fields/Doc';
 
 export interface ScriptSucccess {
     success: true;
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 6501da34a..5679c0a14 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -1,7 +1,7 @@
 import * as rp from 'request-promise';
 import { DocServer } from '../DocServer';
-import { Doc } from '../../new_fields/Doc';
-import { Id } from '../../new_fields/FieldSymbols';
+import { Doc } from '../../fields/Doc';
+import { Id } from '../../fields/FieldSymbols';
 import { Utils } from '../../Utils';
 import { DocumentType } from '../documents/DocumentTypes';
 
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 11d2cafb2..bd743c28e 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -1,8 +1,8 @@
 import { observable, action, runInAction, ObservableMap } from "mobx";
-import { Doc } from "../../new_fields/Doc";
+import { Doc } from "../../fields/Doc";
 import { DocumentView } from "../views/nodes/DocumentView";
 import { computedFn } from "mobx-utils";
-import { List } from "../../new_fields/List";
+import { List } from "../../fields/List";
 
 export namespace SelectionManager {
 
diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts
index 1f6b939d3..ad0309fa7 100644
--- a/src/client/util/SerializationHelper.ts
+++ b/src/client/util/SerializationHelper.ts
@@ -1,5 +1,5 @@
 import { PropSchema, serialize, deserialize, custom, setDefaultModelSchema, getDefaultModelSchema } from "serializr";
-import { Field } from "../../new_fields/Doc";
+import { Field } from "../../fields/Doc";
 import { ClientUtils } from "./ClientUtils";
 
 let serializing = 0;
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 3ce6de80d..dc67145fc 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -1,13 +1,13 @@
 import { observable, runInAction, action } from "mobx";
 import * as React from "react";
 import MainViewModal from "../views/MainViewModal";
-import { Doc, Opt, DocCastAsync } from "../../new_fields/Doc";
+import { Doc, Opt, DocCastAsync } from "../../fields/Doc";
 import { DocServer } from "../DocServer";
-import { Cast, StrCast } from "../../new_fields/Types";
+import { Cast, StrCast } from "../../fields/Types";
 import * as RequestPromise from "request-promise";
 import { Utils } from "../../Utils";
 import "./SharingManager.scss";
-import { Id } from "../../new_fields/FieldSymbols";
+import { Id } from "../../fields/FieldSymbols";
 import { observer } from "mobx-react";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { library } from '@fortawesome/fontawesome-svg-core';
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 6517f2fb9..1ba9fcc32 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -1,14 +1,14 @@
-import { Doc, Opt, DataSym, DocListCast } from '../../new_fields/Doc';
+import { Doc, Opt, DataSym, DocListCast } from '../../fields/Doc';
 import { Touchable } from './Touchable';
 import { computed, action, observable } from 'mobx';
-import { Cast, BoolCast, ScriptCast } from '../../new_fields/Types';
-import { listSpec } from '../../new_fields/Schema';
+import { Cast, BoolCast, ScriptCast } from '../../fields/Types';
+import { listSpec } from '../../fields/Schema';
 import { InkingControl } from './InkingControl';
-import { InkTool } from '../../new_fields/InkField';
+import { InkTool } from '../../fields/InkField';
 import { InteractionUtils } from '../util/InteractionUtils';
-import { List } from '../../new_fields/List';
-import { DateField } from '../../new_fields/DateField';
-import { ScriptField } from '../../new_fields/ScriptField';
+import { List } from '../../fields/List';
+import { DateField } from '../../fields/DateField';
+import { ScriptField } from '../../fields/ScriptField';
 
 
 ///  DocComponent returns a generic React base class used by views that don't have 'fieldKey' props (e.g.,CollectionFreeFormDocumentView, DocumentView)
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 10d9ec401..2db5cd3ba 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -3,9 +3,9 @@ import { faArrowAltCircleDown, faPhotoVideo, faArrowAltCircleUp, faArrowAltCircl
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast } from "../../new_fields/Doc";
-import { RichTextField } from '../../new_fields/RichTextField';
-import { NumCast, StrCast, Cast } from "../../new_fields/Types";
+import { Doc, DocListCast } from "../../fields/Doc";
+import { RichTextField } from '../../fields/RichTextField';
+import { NumCast, StrCast, Cast } from "../../fields/Types";
 import { emptyFunction, setupMoveUpEvents } from "../../Utils";
 import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
 import { UndoManager } from "../util/UndoManager";
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 313d8be23..1f4f45f0e 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -3,10 +3,10 @@ import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faT
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DataSym, Field, WidthSym, HeightSym } from "../../new_fields/Doc";
-import { Document } from '../../new_fields/documentSchemas';
-import { ScriptField } from '../../new_fields/ScriptField';
-import { Cast, StrCast, NumCast } from "../../new_fields/Types";
+import { Doc, DataSym, Field, WidthSym, HeightSym } from "../../fields/Doc";
+import { Document } from '../../fields/documentSchemas';
+import { ScriptField } from '../../fields/ScriptField';
+import { Cast, StrCast, NumCast } from "../../fields/Types";
 import { Utils, setupMoveUpEvents, emptyFunction, returnFalse, simulateMouseClick } from "../../Utils";
 import { DocUtils } from "../documents/Documents";
 import { DocumentType } from '../documents/DocumentTypes';
@@ -17,7 +17,7 @@ import { DocumentButtonBar } from './DocumentButtonBar';
 import './DocumentDecorations.scss';
 import { DocumentView } from "./nodes/DocumentView";
 import React = require("react");
-import { Id } from '../../new_fields/FieldSymbols';
+import { Id } from '../../fields/FieldSymbols';
 import e = require('express');
 import { CollectionDockingView } from './collections/CollectionDockingView';
 import { SnappingManager } from '../util/SnappingManager';
@@ -266,16 +266,16 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         const fixedAspect = first.layoutDoc._nativeWidth ? NumCast(first.layoutDoc._nativeWidth) / NumCast(first.layoutDoc._nativeHeight) : 0;
         if (fixedAspect && (this._resizeHdlId === "documentDecorations-bottomRightResizer" || this._resizeHdlId === "documentDecorations-topLeftResizer")) { // need to generalize for bl and tr drag handles
             const project = (p: number[], a: number[], b: number[]) => {
-                var atob = [b[0] - a[0], b[1] - a[1]];
-                var atop = [p[0] - a[0], p[1] - a[1]];
-                var len = atob[0] * atob[0] + atob[1] * atob[1];
-                var dot = atop[0] * atob[0] + atop[1] * atob[1];
-                var t = dot / len;
+                const atob = [b[0] - a[0], b[1] - a[1]];
+                const atop = [p[0] - a[0], p[1] - a[1]];
+                const len = atob[0] * atob[0] + atob[1] * atob[1];
+                let dot = atop[0] * atob[0] + atop[1] * atob[1];
+                const t = dot / len;
                 dot = (b[0] - a[0]) * (p[1] - a[1]) - (b[1] - a[1]) * (p[0] - a[0]);
                 return [a[0] + atob[0] * t, a[1] + atob[1] * t];
-            }
+            };
             const tl = first.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
-            const drag = project([e.clientX + this._offX, e.clientY + this._offY], tl, [tl[0] + fixedAspect, tl[1] + 1])
+            const drag = project([e.clientX + this._offX, e.clientY + this._offY], tl, [tl[0] + fixedAspect, tl[1] + 1]);
             thisPt = DragManager.snapDragAspect(drag, fixedAspect);
         } else {
             thisPt = DragManager.snapDrag(e, -this._offX, -this._offY, this._offX, this._offY);
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index c51173ad3..e0e205df9 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -2,8 +2,8 @@ import React = require('react');
 import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as Autosuggest from 'react-autosuggest';
-import { ObjectField } from '../../new_fields/ObjectField';
-import { SchemaHeaderField } from '../../new_fields/SchemaHeaderField';
+import { ObjectField } from '../../fields/ObjectField';
+import { SchemaHeaderField } from '../../fields/SchemaHeaderField';
 import "./EditableView.scss";
 
 export interface EditableProps {
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 812ff3b93..aadf5f535 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -6,13 +6,13 @@ import { computed, observable, action, runInAction, IReactionDisposer, reaction,
 import { GestureUtils } from "../../pen-gestures/GestureUtils";
 import { InteractionUtils } from "../util/InteractionUtils";
 import { InkingControl } from "./InkingControl";
-import { InkTool, InkData } from "../../new_fields/InkField";
-import { Doc } from "../../new_fields/Doc";
+import { InkTool, InkData } from "../../fields/InkField";
+import { Doc } from "../../fields/Doc";
 import { LinkManager } from "../util/LinkManager";
 import { DocUtils, Docs } from "../documents/Documents";
 import { undoBatch } from "../util/UndoManager";
 import { Scripting } from "../util/Scripting";
-import { FieldValue, Cast, NumCast, BoolCast } from "../../new_fields/Types";
+import { FieldValue, Cast, NumCast, BoolCast } from "../../fields/Types";
 import { CurrentUserUtils } from "../util/CurrentUserUtils";
 import HorizontalPalette from "./Palette";
 import { Utils, emptyPath, emptyFunction, returnFalse, returnOne, returnEmptyString, returnTrue, numberRange, returnZero } from "../../Utils";
@@ -22,9 +22,9 @@ import { DocumentContentsView } from "./nodes/DocumentContentsView";
 import { CognitiveServices } from "../cognitive_services/CognitiveServices";
 import { DocServer } from "../DocServer";
 import htmlToImage from "html-to-image";
-import { ScriptField } from "../../new_fields/ScriptField";
-import { listSpec } from "../../new_fields/Schema";
-import { List } from "../../new_fields/List";
+import { ScriptField } from "../../fields/ScriptField";
+import { listSpec } from "../../fields/Schema";
+import { List } from "../../fields/List";
 import { CollectionViewType } from "./collections/CollectionView";
 import TouchScrollableMenu, { TouchScrollableMenuItem } from "./TouchScrollableMenu";
 import MobileInterface from "../../mobile/MobileInterface";
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index b52a0063b..255142771 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -4,23 +4,23 @@ import { CollectionDockingView } from "./collections/CollectionDockingView";
 import { MainView } from "./MainView";
 import { DragManager } from "../util/DragManager";
 import { action, runInAction } from "mobx";
-import { Doc, DocListCast } from "../../new_fields/Doc";
+import { Doc, DocListCast } from "../../fields/Doc";
 import { DictationManager } from "../util/DictationManager";
 import SharingManager from "../util/SharingManager";
-import { Cast, PromiseValue, NumCast } from "../../new_fields/Types";
-import { ScriptField } from "../../new_fields/ScriptField";
+import { Cast, PromiseValue, NumCast } from "../../fields/Types";
+import { ScriptField } from "../../fields/ScriptField";
 import { InkingControl } from "./InkingControl";
-import { InkTool } from "../../new_fields/InkField";
+import { InkTool } from "../../fields/InkField";
 import { DocumentView } from "./nodes/DocumentView";
 import GoogleAuthenticationManager from "../apis/GoogleAuthenticationManager";
 import { CollectionFreeFormView } from "./collections/collectionFreeForm/CollectionFreeFormView";
 import { MarqueeView } from "./collections/collectionFreeForm/MarqueeView";
-import { Id } from "../../new_fields/FieldSymbols";
+import { Id } from "../../fields/FieldSymbols";
 import { DocumentDecorations } from "./DocumentDecorations";
 import { DocumentType } from "../documents/DocumentTypes";
 import { DocServer } from "../DocServer";
-import { List } from "../../new_fields/List";
-import { DateField } from "../../new_fields/DateField";
+import { List } from "../../fields/List";
+import { DateField } from "../../fields/DateField";
 
 const modifiers = ["control", "meta", "shift", "alt"];
 type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo | Promise<KeyControlInfo>;
diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx
index 5115995b0..156f58ec1 100644
--- a/src/client/views/InkingControl.tsx
+++ b/src/client/views/InkingControl.tsx
@@ -1,8 +1,8 @@
 import { action, computed, observable } from "mobx";
 import { ColorState } from 'react-color';
-import { Doc } from "../../new_fields/Doc";
-import { InkTool } from "../../new_fields/InkField";
-import { FieldValue, NumCast, StrCast } from "../../new_fields/Types";
+import { Doc } from "../../fields/Doc";
+import { InkTool } from "../../fields/InkField";
+import { FieldValue, NumCast, StrCast } from "../../fields/Types";
 import { CurrentUserUtils } from "../util/CurrentUserUtils";
 import { Scripting } from "../util/Scripting";
 import { SelectionManager } from "../util/SelectionManager";
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 7a318d5c2..25ea50a27 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -1,14 +1,14 @@
 import { observer } from "mobx-react";
-import { documentSchema } from "../../new_fields/documentSchemas";
-import { InkData, InkField, InkTool } from "../../new_fields/InkField";
-import { makeInterface } from "../../new_fields/Schema";
-import { Cast, StrCast, NumCast } from "../../new_fields/Types";
+import { documentSchema } from "../../fields/documentSchemas";
+import { InkData, InkField, InkTool } from "../../fields/InkField";
+import { makeInterface } from "../../fields/Schema";
+import { Cast, StrCast, NumCast } from "../../fields/Types";
 import { ViewBoxBaseComponent } from "./DocComponent";
 import { InkingControl } from "./InkingControl";
 import "./InkingStroke.scss";
 import { FieldView, FieldViewProps } from "./nodes/FieldView";
 import React = require("react");
-import { TraceMobx } from "../../new_fields/util";
+import { TraceMobx } from "../../fields/util";
 import { InteractionUtils } from "../util/InteractionUtils";
 import { ContextMenu } from "./ContextMenu";
 import { CognitiveServices } from "../cognitive_services/CognitiveServices";
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 9bc08de3e..978cf7868 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -13,12 +13,12 @@ import { observer } from 'mobx-react';
 import "normalize.css";
 import * as React from 'react';
 import Measure from 'react-measure';
-import { Doc, DocListCast, Field, Opt } from '../../new_fields/Doc';
-import { Id } from '../../new_fields/FieldSymbols';
-import { List } from '../../new_fields/List';
-import { listSpec } from '../../new_fields/Schema';
-import { BoolCast, Cast, FieldValue, StrCast } from '../../new_fields/Types';
-import { TraceMobx } from '../../new_fields/util';
+import { Doc, DocListCast, Field, Opt } from '../../fields/Doc';
+import { Id } from '../../fields/FieldSymbols';
+import { List } from '../../fields/List';
+import { listSpec } from '../../fields/Schema';
+import { BoolCast, Cast, FieldValue, StrCast } from '../../fields/Types';
+import { TraceMobx } from '../../fields/util';
 import { CurrentUserUtils } from '../util/CurrentUserUtils';
 import { emptyFunction, emptyPath, returnFalse, returnOne, returnZero, returnTrue, Utils } from '../../Utils';
 import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager';
@@ -48,7 +48,7 @@ import { RadialMenu } from './nodes/RadialMenu';
 import { OverlayView } from './OverlayView';
 import PDFMenu from './pdf/PDFMenu';
 import { PreviewCursor } from './PreviewCursor';
-import { ScriptField } from '../../new_fields/ScriptField';
+import { ScriptField } from '../../fields/ScriptField';
 import { TimelineMenu } from './animationtimeline/TimelineMenu';
 import { DragManager } from '../util/DragManager';
 import { SnappingManager } from '../util/SnappingManager';
diff --git a/src/client/views/MainViewNotifs.tsx b/src/client/views/MainViewNotifs.tsx
index 82e07c449..05f890485 100644
--- a/src/client/views/MainViewNotifs.tsx
+++ b/src/client/views/MainViewNotifs.tsx
@@ -2,7 +2,7 @@ import { action, computed, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import "normalize.css";
 import * as React from 'react';
-import { Doc, DocListCast, Opt } from '../../new_fields/Doc';
+import { Doc, DocListCast, Opt } from '../../fields/Doc';
 import { emptyFunction } from '../../Utils';
 import { SetupDrag } from '../util/DragManager';
 import "./MainViewNotifs.scss";
diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx
index 8bc80ed06..e100d3f52 100644
--- a/src/client/views/MetadataEntryMenu.tsx
+++ b/src/client/views/MetadataEntryMenu.tsx
@@ -3,7 +3,7 @@ import "./MetadataEntryMenu.scss";
 import { observer } from 'mobx-react';
 import { observable, action, runInAction, trace, computed, IReactionDisposer, reaction } from 'mobx';
 import { KeyValueBox } from './nodes/KeyValueBox';
-import { Doc, Field, DocListCastAsync } from '../../new_fields/Doc';
+import { Doc, Field, DocListCastAsync } from '../../fields/Doc';
 import * as Autosuggest from 'react-autosuggest';
 import { undoBatch } from '../util/UndoManager';
 import { emptyFunction, emptyPath } from '../../Utils';
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index afb6bfb7d..bfa44fe47 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -1,9 +1,9 @@
 import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
 import * as React from "react";
-import { Doc, DocListCast, Opt } from "../../new_fields/Doc";
-import { Id } from "../../new_fields/FieldSymbols";
-import { NumCast } from "../../new_fields/Types";
+import { Doc, DocListCast, Opt } from "../../fields/Doc";
+import { Id } from "../../fields/FieldSymbols";
+import { NumCast } from "../../fields/Types";
 import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero, Utils } from "../../Utils";
 import { Transform } from "../util/Transform";
 import { CollectionFreeFormLinksView } from "./collections/collectionFreeForm/CollectionFreeFormLinksView";
diff --git a/src/client/views/Palette.tsx b/src/client/views/Palette.tsx
index 63744cb50..108eb83d6 100644
--- a/src/client/views/Palette.tsx
+++ b/src/client/views/Palette.tsx
@@ -1,8 +1,8 @@
 import { IReactionDisposer, observable, reaction } from "mobx";
 import { observer } from "mobx-react";
 import * as React from "react";
-import { Doc } from "../../new_fields/Doc";
-import { NumCast } from "../../new_fields/Types";
+import { Doc } from "../../fields/Doc";
+import { NumCast } from "../../fields/Types";
 import { emptyFunction, emptyPath, returnEmptyString, returnZero, returnFalse, returnOne, returnTrue } from "../../Utils";
 import { Transform } from "../util/Transform";
 import { DocumentView } from "./nodes/DocumentView";
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index f50ac34c8..dd65681d4 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -4,11 +4,11 @@ import "normalize.css";
 import * as React from 'react';
 import "./PreviewCursor.scss";
 import { Docs } from '../documents/Documents';
-import { Doc } from '../../new_fields/Doc';
+import { Doc } from '../../fields/Doc';
 import { Transform } from "../util/Transform";
 import { DocServer } from '../DocServer';
 import { undoBatch } from '../util/UndoManager';
-import { NumCast } from '../../new_fields/Types';
+import { NumCast } from '../../fields/Types';
 
 @observer
 export class PreviewCursor extends React.Component<{}> {
diff --git a/src/client/views/RecommendationsBox.tsx b/src/client/views/RecommendationsBox.tsx
index e66fd3eb4..8ca81c070 100644
--- a/src/client/views/RecommendationsBox.tsx
+++ b/src/client/views/RecommendationsBox.tsx
@@ -3,17 +3,17 @@ import React = require("react");
 import { observable, action, computed, runInAction } from "mobx";
 import Measure from "react-measure";
 import "./RecommendationsBox.scss";
-import { Doc, DocListCast, WidthSym, HeightSym } from "../../new_fields/Doc";
+import { Doc, DocListCast, WidthSym, HeightSym } from "../../fields/Doc";
 import { DocumentIcon } from "./nodes/DocumentIcon";
-import { StrCast, NumCast } from "../../new_fields/Types";
+import { StrCast, NumCast } from "../../fields/Types";
 import { returnFalse, emptyFunction, returnEmptyString, returnOne, emptyPath, returnZero } from "../../Utils";
 import { Transform } from "../util/Transform";
-import { ObjectField } from "../../new_fields/ObjectField";
+import { ObjectField } from "../../fields/ObjectField";
 import { DocumentView } from "./nodes/DocumentView";
 import { DocumentType } from '../documents/DocumentTypes';
 import { ClientRecommender } from "../ClientRecommender";
 import { DocServer } from "../DocServer";
-import { Id } from "../../new_fields/FieldSymbols";
+import { Id } from "../../fields/FieldSymbols";
 import { FieldView, FieldViewProps } from "./nodes/FieldView";
 import { DocumentManager } from "../util/DocumentManager";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx
index 66d3b937e..888f84dfa 100644
--- a/src/client/views/ScriptBox.tsx
+++ b/src/client/views/ScriptBox.tsx
@@ -5,11 +5,11 @@ import { observable, action } from "mobx";
 import "./ScriptBox.scss";
 import { OverlayView } from "./OverlayView";
 import { DocumentIconContainer } from "./nodes/DocumentIcon";
-import { Opt, Doc } from "../../new_fields/Doc";
+import { Opt, Doc } from "../../fields/Doc";
 import { emptyFunction } from "../../Utils";
-import { ScriptCast } from "../../new_fields/Types";
+import { ScriptCast } from "../../fields/Types";
 import { CompileScript } from "../util/Scripting";
-import { ScriptField } from "../../new_fields/ScriptField";
+import { ScriptField } from "../../fields/ScriptField";
 import { DragManager } from "../util/DragManager";
 import { EditableView } from "./EditableView";
 import { getEffectiveTypeRoots } from "typescript";
diff --git a/src/client/views/SearchDocBox.tsx b/src/client/views/SearchDocBox.tsx
index 7bd689b19..e038d8213 100644
--- a/src/client/views/SearchDocBox.tsx
+++ b/src/client/views/SearchDocBox.tsx
@@ -3,9 +3,9 @@ import { faBullseye, faLink } from "@fortawesome/free-solid-svg-icons";
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
 //import "./SearchBoxDoc.scss";
-import { Doc, DocListCast } from "../../new_fields/Doc";
-import { Id } from "../../new_fields/FieldSymbols";
-import { BoolCast, Cast, NumCast, StrCast } from "../../new_fields/Types";
+import { Doc, DocListCast } from "../../fields/Doc";
+import { Id } from "../../fields/FieldSymbols";
+import { BoolCast, Cast, NumCast, StrCast } from "../../fields/Types";
 import { returnFalse, returnZero } from "../../Utils";
 import { Docs } from "../documents/Documents";
 import { SearchUtil } from "../util/SearchUtil";
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index 43debfe99..f5e95e4fd 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -6,15 +6,15 @@ import './TemplateMenu.scss';
 import { DocumentView } from "./nodes/DocumentView";
 import { Template } from "./Templates";
 import React = require("react");
-import { Doc, DocListCast } from "../../new_fields/Doc";
+import { Doc, DocListCast } from "../../fields/Doc";
 import { Docs, } from "../documents/Documents";
-import { StrCast, Cast } from "../../new_fields/Types";
+import { StrCast, Cast } from "../../fields/Types";
 import { CollectionTreeView } from "./collections/CollectionTreeView";
 import { returnTrue, emptyFunction, returnFalse, returnOne, emptyPath, returnZero } from "../../Utils";
 import { Transform } from "../util/Transform";
-import { ScriptField, ComputedField } from "../../new_fields/ScriptField";
+import { ScriptField, ComputedField } from "../../fields/ScriptField";
 import { Scripting } from "../util/Scripting";
-import { List } from "../../new_fields/List";
+import { List } from "../../fields/List";
 
 @observer
 class TemplateToggle extends React.Component<{ template: Template, checked: boolean, toggle: (event: React.ChangeEvent<HTMLInputElement>, template: Template) => void }> {
diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx
index bbd7b2676..92b0f05b3 100644
--- a/src/client/views/animationtimeline/Keyframe.tsx
+++ b/src/client/views/animationtimeline/Keyframe.tsx
@@ -4,10 +4,10 @@ import "./Timeline.scss";
 import "../globalCssVariables.scss";
 import { observer } from "mobx-react";
 import { observable, reaction, action, IReactionDisposer, observe, computed, runInAction, trace } from "mobx";
-import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../new_fields/Doc";
-import { Cast, NumCast } from "../../../new_fields/Types";
-import { List } from "../../../new_fields/List";
-import { createSchema, defaultSpec, makeInterface, listSpec } from "../../../new_fields/Schema";
+import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../fields/Doc";
+import { Cast, NumCast } from "../../../fields/Types";
+import { List } from "../../../fields/List";
+import { createSchema, defaultSpec, makeInterface, listSpec } from "../../../fields/Schema";
 import { Transform } from "../../util/Transform";
 import { TimelineMenu } from "./TimelineMenu";
 import { Docs } from "../../documents/Documents";
diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx
index 466cbb867..30692944d 100644
--- a/src/client/views/animationtimeline/Timeline.tsx
+++ b/src/client/views/animationtimeline/Timeline.tsx
@@ -1,12 +1,12 @@
 import * as React from "react";
 import "./Timeline.scss";
-import { listSpec } from "../../../new_fields/Schema";
+import { listSpec } from "../../../fields/Schema";
 import { observer } from "mobx-react";
 import { Track } from "./Track";
 import { observable, action, computed, runInAction, IReactionDisposer, reaction, trace } from "mobx";
-import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
-import { List } from "../../../new_fields/List";
-import { Doc, DocListCast } from "../../../new_fields/Doc";
+import { Cast, NumCast, StrCast, BoolCast } from "../../../fields/Types";
+import { List } from "../../../fields/List";
+import { Doc, DocListCast } from "../../../fields/Doc";
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { faPlayCircle, faBackward, faForward, faGripLines, faPauseCircle, faEyeSlash, faEye, faCheckCircle, faTimesCircle } from "@fortawesome/free-solid-svg-icons";
 import { ContextMenu } from "../ContextMenu";
diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx
index 461db4858..fc96c320a 100644
--- a/src/client/views/animationtimeline/Track.tsx
+++ b/src/client/views/animationtimeline/Track.tsx
@@ -1,12 +1,12 @@
 import { action, computed, intercept, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import * as React from "react";
-import { Doc, DocListCast, Opt, DocListCastAsync } from "../../../new_fields/Doc";
-import { Copy } from "../../../new_fields/FieldSymbols";
-import { List } from "../../../new_fields/List";
-import { ObjectField } from "../../../new_fields/ObjectField";
-import { listSpec } from "../../../new_fields/Schema";
-import { Cast, NumCast } from "../../../new_fields/Types";
+import { Doc, DocListCast, Opt, DocListCastAsync } from "../../../fields/Doc";
+import { Copy } from "../../../fields/FieldSymbols";
+import { List } from "../../../fields/List";
+import { ObjectField } from "../../../fields/ObjectField";
+import { listSpec } from "../../../fields/Schema";
+import { Cast, NumCast } from "../../../fields/Types";
 import { Transform } from "../../util/Transform";
 import { Keyframe, KeyframeFunc, RegionData } from "./Keyframe";
 import "./Track.scss";
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index a04136e51..39bb9bc23 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -2,18 +2,18 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { observable, computed } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { documentSchema, collectionSchema } from '../../../new_fields/documentSchemas';
-import { makeInterface } from '../../../new_fields/Schema';
-import { NumCast, StrCast, ScriptCast, Cast } from '../../../new_fields/Types';
+import { documentSchema, collectionSchema } from '../../../fields/documentSchemas';
+import { makeInterface } from '../../../fields/Schema';
+import { NumCast, StrCast, ScriptCast, Cast } from '../../../fields/Types';
 import { DragManager } from '../../util/DragManager';
 import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView';
 import "./CollectionCarouselView.scss";
 import { CollectionSubView } from './CollectionSubView';
 import { faCaretLeft, faCaretRight } from '@fortawesome/free-solid-svg-icons';
-import { Doc } from '../../../new_fields/Doc';
+import { Doc } from '../../../fields/Doc';
 import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
 import { ContextMenu } from '../ContextMenu';
-import { ObjectField } from '../../../new_fields/ObjectField';
+import { ObjectField } from '../../../fields/ObjectField';
 import { returnFalse } from '../../../Utils';
 
 type CarouselDocument = makeInterface<[typeof documentSchema, typeof collectionSchema]>;
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 581625222..745476ef7 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -7,13 +7,13 @@ import { observer } from "mobx-react";
 import * as ReactDOM from 'react-dom';
 import Measure from "react-measure";
 import * as GoldenLayout from "../../../client/goldenLayout";
-import { DateField } from '../../../new_fields/DateField';
-import { Doc, DocListCast, Field, Opt, DataSym } from "../../../new_fields/Doc";
-import { Id } from '../../../new_fields/FieldSymbols';
-import { List } from '../../../new_fields/List';
-import { FieldId } from "../../../new_fields/RefField";
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { TraceMobx } from '../../../new_fields/util';
+import { DateField } from '../../../fields/DateField';
+import { Doc, DocListCast, Field, Opt, DataSym } from "../../../fields/Doc";
+import { Id } from '../../../fields/FieldSymbols';
+import { List } from '../../../fields/List';
+import { FieldId } from "../../../fields/RefField";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
+import { TraceMobx } from '../../../fields/util';
 import { emptyFunction, returnOne, returnTrue, Utils, returnZero } from "../../../Utils";
 import { DocServer } from "../../DocServer";
 import { Docs } from '../../documents/Documents';
@@ -196,15 +196,16 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         if (!CollectionDockingView.Instance) return undefined;
         const instance = CollectionDockingView.Instance;
         const replaceTab = (doc: Doc, child: any): Opt<Doc> => {
-            for (let i = 0; i < child.contentItems.length; i++) {
-                if (child.contentItems[i].isRow || child.contentItems[i].isColumn || child.contentItems[i].isStack) {
-                    const val = replaceTab(doc, child.contentItems[i]);
+            for (const contentItem of child.contentItems) {
+                const { config, isStack, isRow, isColumn } = contentItem;
+                if (isRow || isColumn || isStack) {
+                    const val = replaceTab(doc, contentItem);
                     if (val) return val;
-                } else if (child.contentItems[i].config.component === "DocumentFrameRenderer" &&
-                    child.contentItems[i].config.props.documentId === doc[Id]) {
+                } else if (config.component === "DocumentFrameRenderer" &&
+                    config.props.documentId === doc[Id]) {
                     const alias = Doc.MakeAlias(doc);
-                    child.contentItems[i].config.props.documentId = alias[Id];
-                    child.contentItems[i].config.title = alias.title;
+                    config.props.documentId = alias[Id];
+                    config.title = alias.title;
                     instance.stateChanged();
                     return alias;
                 }
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index 344dca23a..f1002044a 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -1,9 +1,9 @@
 import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { Doc, HeightSym, WidthSym } from '../../../new_fields/Doc';
-import { makeInterface } from '../../../new_fields/Schema';
-import { BoolCast, NumCast, StrCast, Cast, ScriptCast } from '../../../new_fields/Types';
+import { Doc, HeightSym, WidthSym } from '../../../fields/Doc';
+import { makeInterface } from '../../../fields/Schema';
+import { BoolCast, NumCast, StrCast, Cast, ScriptCast } from '../../../fields/Types';
 import { emptyFunction, returnEmptyString, returnOne, returnTrue, Utils, returnFalse, returnZero } from '../../../Utils';
 import { DragManager } from '../../util/DragManager';
 import { Transform } from '../../util/Transform';
@@ -11,8 +11,8 @@ import "./CollectionLinearView.scss";
 import { CollectionViewType } from './CollectionView';
 import { CollectionSubView } from './CollectionSubView';
 import { DocumentView } from '../nodes/DocumentView';
-import { documentSchema } from '../../../new_fields/documentSchemas';
-import { Id } from '../../../new_fields/FieldSymbols';
+import { documentSchema } from '../../../fields/documentSchemas';
+import { Id } from '../../../fields/FieldSymbols';
 
 
 type LinearDocument = makeInterface<[typeof documentSchema,]>;
diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx
index 618285293..da902cecd 100644
--- a/src/client/views/collections/CollectionMapView.tsx
+++ b/src/client/views/collections/CollectionMapView.tsx
@@ -1,10 +1,10 @@
 import { GoogleApiWrapper, Map as GeoMap, MapProps as IMapProps, Marker } from "google-maps-react";
 import { observer } from "mobx-react";
-import { Doc, Opt, DocListCast, FieldResult, Field } from "../../../new_fields/Doc";
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { makeInterface } from "../../../new_fields/Schema";
-import { Cast, NumCast, ScriptCast, StrCast } from "../../../new_fields/Types";
+import { Doc, Opt, DocListCast, FieldResult, Field } from "../../../fields/Doc";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { Id } from "../../../fields/FieldSymbols";
+import { makeInterface } from "../../../fields/Schema";
+import { Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types";
 import "./CollectionMapView.scss";
 import { CollectionSubView } from "./CollectionSubView";
 import React = require("react");
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 95c7643c9..d6cb174cc 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -4,10 +4,10 @@ import { faPalette } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc } from "../../../new_fields/Doc";
-import { PastelSchemaPalette, SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { StrCast, NumCast } from "../../../new_fields/Types";
+import { Doc } from "../../../fields/Doc";
+import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
+import { ScriptField } from "../../../fields/ScriptField";
+import { StrCast, NumCast } from "../../../fields/Types";
 import { numberRange, setupMoveUpEvents, emptyFunction } from "../../../Utils";
 import { Docs } from "../../documents/Documents";
 import { DragManager } from "../../util/DragManager";
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx
index d3ae21f3a..e3bcf2a21 100644
--- a/src/client/views/collections/CollectionPileView.tsx
+++ b/src/client/views/collections/CollectionPileView.tsx
@@ -1,8 +1,8 @@
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { HeightSym, Opt, WidthSym } from "../../../new_fields/Doc";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { BoolCast, NumCast, StrCast } from "../../../new_fields/Types";
+import { HeightSym, Opt, WidthSym } from "../../../fields/Doc";
+import { ScriptField } from "../../../fields/ScriptField";
+import { BoolCast, NumCast, StrCast } from "../../../fields/Types";
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from "../ContextMenuItem";
 import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView";
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 8a5450b0c..62aed67ed 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -4,8 +4,8 @@ import { observer } from "mobx-react";
 import { CellInfo } from "react-table";
 import "react-table/react-table.css";
 import { emptyFunction, returnFalse, returnZero, returnOne } from "../../../Utils";
-import { Doc, DocListCast, Field, Opt } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
+import { Doc, DocListCast, Field, Opt } from "../../../fields/Doc";
+import { Id } from "../../../fields/FieldSymbols";
 import { KeyCodes } from "../../util/KeyCodes";
 import { SetupDrag, DragManager } from "../../util/DragManager";
 import { CompileScript } from "../../util/Scripting";
@@ -16,11 +16,11 @@ import { EditableView } from "../EditableView";
 import { FieldView, FieldViewProps } from "../nodes/FieldView";
 import "./CollectionSchemaView.scss";
 import { CollectionView } from "./CollectionView";
-import { NumCast, StrCast, BoolCast, FieldValue, Cast } from "../../../new_fields/Types";
+import { NumCast, StrCast, BoolCast, FieldValue, Cast } from "../../../fields/Types";
 import { Docs } from "../../documents/Documents";
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faExpand } from '@fortawesome/free-solid-svg-icons';
-import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
 import { undoBatch } from "../../util/UndoManager";
 import { SnappingManager } from "../../util/SnappingManager";
 
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 507ee89e4..dae0600b1 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -7,7 +7,7 @@ import { library, IconProp } from "@fortawesome/fontawesome-svg-core";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { ColumnType } from "./CollectionSchemaView";
 import { faFile } from "@fortawesome/free-regular-svg-icons";
-import { SchemaHeaderField, PastelSchemaPalette } from "../../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField, PastelSchemaPalette } from "../../../fields/SchemaHeaderField";
 import { undoBatch } from "../../util/UndoManager";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 5aec46a83..6f1e8ac1f 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -2,16 +2,16 @@ import React = require("react");
 import { ReactTableDefaults, TableCellRenderer, RowInfo } from "react-table";
 import "./CollectionSchemaView.scss";
 import { Transform } from "../../util/Transform";
-import { Doc } from "../../../new_fields/Doc";
+import { Doc } from "../../../fields/Doc";
 import { DragManager, SetupDrag, dropActionType } from "../../util/DragManager";
-import { Cast, FieldValue, StrCast } from "../../../new_fields/Types";
+import { Cast, FieldValue, StrCast } from "../../../fields/Types";
 import { ContextMenu } from "../ContextMenu";
 import { action } from "mobx";
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faGripVertical, faTrash } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { DocumentManager } from "../../util/DocumentManager";
-import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
 import { undoBatch } from "../../util/UndoManager";
 import { SnappingManager } from "../../util/SnappingManager";
 
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 51ad6c81b..35f892d65 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -6,13 +6,13 @@ import { action, computed, observable, untracked } from "mobx";
 import { observer } from "mobx-react";
 import ReactTable, { CellInfo, Column, ComponentPropsGetterR, Resize, SortingRule } from "react-table";
 import "react-table/react-table.css";
-import { Doc, DocListCast, Field, Opt } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { List } from "../../../new_fields/List";
-import { listSpec } from "../../../new_fields/Schema";
-import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
-import { ComputedField } from "../../../new_fields/ScriptField";
-import { Cast, FieldValue, NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
+import { Doc, DocListCast, Field, Opt } from "../../../fields/Doc";
+import { Id } from "../../../fields/FieldSymbols";
+import { List } from "../../../fields/List";
+import { listSpec } from "../../../fields/Schema";
+import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
+import { ComputedField } from "../../../fields/ScriptField";
+import { Cast, FieldValue, NumCast, StrCast, BoolCast } from "../../../fields/Types";
 import { Docs, DocumentOptions } from "../../documents/Documents";
 import { CompileScript, Transformer, ts } from "../../util/Scripting";
 import { Transform } from "../../util/Transform";
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index d97f26daf..cc6077d98 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -4,14 +4,14 @@ import { CursorProperty } from "csstype";
 import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import Switch from 'rc-switch';
-import { DataSym, Doc, HeightSym, WidthSym } from "../../../new_fields/Doc";
-import { collectionSchema, documentSchema } from "../../../new_fields/documentSchemas";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { List } from "../../../new_fields/List";
-import { listSpec, makeInterface } from "../../../new_fields/Schema";
-import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
-import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../new_fields/Types";
-import { TraceMobx } from "../../../new_fields/util";
+import { DataSym, Doc, HeightSym, WidthSym } from "../../../fields/Doc";
+import { collectionSchema, documentSchema } from "../../../fields/documentSchemas";
+import { Id } from "../../../fields/FieldSymbols";
+import { List } from "../../../fields/List";
+import { listSpec, makeInterface } from "../../../fields/Schema";
+import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
+import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types";
+import { TraceMobx } from "../../../fields/util";
 import { emptyFunction, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils, smoothScroll } from "../../../Utils";
 import { DragManager, dropActionType } from "../../util/DragManager";
 import { Transform } from "../../util/Transform";
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index dccef7983..53435ccc9 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -4,13 +4,13 @@ import { faPalette } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast } from "../../../new_fields/Doc";
-import { RichTextField } from "../../../new_fields/RichTextField";
-import { PastelSchemaPalette, SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { NumCast, StrCast, Cast } from "../../../new_fields/Types";
-import { ImageField } from "../../../new_fields/URLField";
-import { TraceMobx } from "../../../new_fields/util";
+import { Doc, DocListCast } from "../../../fields/Doc";
+import { RichTextField } from "../../../fields/RichTextField";
+import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
+import { ScriptField } from "../../../fields/ScriptField";
+import { NumCast, StrCast, Cast } from "../../../fields/Types";
+import { ImageField } from "../../../fields/URLField";
+import { TraceMobx } from "../../../fields/util";
 import { Docs, DocUtils } from "../../documents/Documents";
 import { DragManager } from "../../util/DragManager";
 import { Transform } from "../../util/Transform";
@@ -21,7 +21,7 @@ import { EditableView } from "../EditableView";
 import { CollectionStackingView } from "./CollectionStackingView";
 import { setupMoveUpEvents, emptyFunction } from "../../../Utils";
 import "./CollectionStackingView.scss";
-import { listSpec } from "../../../new_fields/Schema";
+import { listSpec } from "../../../fields/Schema";
 import { SnappingManager } from "../../util/SnappingManager";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
diff --git a/src/client/views/collections/CollectionStaffView.tsx b/src/client/views/collections/CollectionStaffView.tsx
index 5b9a69bf7..c5c3f96e8 100644
--- a/src/client/views/collections/CollectionStaffView.tsx
+++ b/src/client/views/collections/CollectionStaffView.tsx
@@ -1,7 +1,7 @@
 import { CollectionSubView } from "./CollectionSubView";
 import React = require("react");
 import { computed, action, IReactionDisposer, reaction, runInAction, observable } from "mobx";
-import { NumCast } from "../../../new_fields/Types";
+import { NumCast } from "../../../fields/Types";
 import "./CollectionStaffView.scss";
 import { observer } from "mobx-react";
 
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index bff6d121b..a4e843c8e 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -1,12 +1,12 @@
 import { action, computed, IReactionDisposer, reaction } from "mobx";
 import { basename } from 'path';
-import CursorField from "../../../new_fields/CursorField";
-import { Doc, Opt } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { List } from "../../../new_fields/List";
-import { listSpec } from "../../../new_fields/Schema";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { Cast, ScriptCast } from "../../../new_fields/Types";
+import CursorField from "../../../fields/CursorField";
+import { Doc, Opt } from "../../../fields/Doc";
+import { Id } from "../../../fields/FieldSymbols";
+import { List } from "../../../fields/List";
+import { listSpec } from "../../../fields/Schema";
+import { ScriptField } from "../../../fields/ScriptField";
+import { Cast, ScriptCast } from "../../../fields/Types";
 import { GestureUtils } from "../../../pen-gestures/GestureUtils";
 import { CurrentUserUtils } from "../../util/CurrentUserUtils";
 import { Upload } from "../../../server/SharedMediaTypes";
diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx
index a2d4774c8..15bc0bfd5 100644
--- a/src/client/views/collections/CollectionTimeView.tsx
+++ b/src/client/views/collections/CollectionTimeView.tsx
@@ -1,11 +1,11 @@
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, Opt, DocCastAsync } from "../../../new_fields/Doc";
-import { List } from "../../../new_fields/List";
-import { ObjectField } from "../../../new_fields/ObjectField";
-import { RichTextField } from "../../../new_fields/RichTextField";
-import { ComputedField, ScriptField } from "../../../new_fields/ScriptField";
-import { NumCast, StrCast, BoolCast, Cast } from "../../../new_fields/Types";
+import { Doc, Opt, DocCastAsync } from "../../../fields/Doc";
+import { List } from "../../../fields/List";
+import { ObjectField } from "../../../fields/ObjectField";
+import { RichTextField } from "../../../fields/RichTextField";
+import { ComputedField, ScriptField } from "../../../fields/ScriptField";
+import { NumCast, StrCast, BoolCast, Cast } from "../../../fields/Types";
 import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../../Utils";
 import { Scripting } from "../../util/Scripting";
 import { ContextMenu } from "../ContextMenu";
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 2f332e77d..3e99af724 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,13 +1,13 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
-import { DataSym, Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from '../../../new_fields/Doc';
-import { Id } from '../../../new_fields/FieldSymbols';
-import { List } from '../../../new_fields/List';
-import { PrefetchProxy } from '../../../new_fields/Proxy';
-import { Document, listSpec } from '../../../new_fields/Schema';
-import { ComputedField, ScriptField } from '../../../new_fields/ScriptField';
-import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../new_fields/Types';
+import { DataSym, Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
+import { Id } from '../../../fields/FieldSymbols';
+import { List } from '../../../fields/List';
+import { PrefetchProxy } from '../../../fields/Proxy';
+import { Document, listSpec } from '../../../fields/Schema';
+import { ComputedField, ScriptField } from '../../../fields/ScriptField';
+import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
 import { emptyFunction, emptyPath, returnFalse, returnOne, returnTrue, returnZero, simulateMouseClick, Utils } from '../../../Utils';
 import { Docs, DocUtils } from '../../documents/Documents';
 import { DocumentType } from "../../documents/DocumentTypes";
@@ -32,7 +32,7 @@ import "./CollectionTreeView.scss";
 import { CollectionViewType } from './CollectionView';
 import React = require("react");
 import { makeTemplate } from '../../util/DropConverter';
-import { TraceMobx } from '../../../new_fields/util';
+import { TraceMobx } from '../../../fields/util';
 
 export interface TreeViewProps {
     document: Doc;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 4b3b2e234..3b2e5e4fc 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -7,12 +7,12 @@ import { observer } from "mobx-react";
 import * as React from 'react';
 import Lightbox from 'react-image-lightbox-with-rotate';
 import 'react-image-lightbox-with-rotate/style.css'; // This only needs to be imported once in your app
-import { DateField } from '../../../new_fields/DateField';
-import { DataSym, Doc, DocListCast, Field, Opt } from '../../../new_fields/Doc';
-import { List } from '../../../new_fields/List';
-import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from '../../../new_fields/Types';
-import { ImageField } from '../../../new_fields/URLField';
-import { TraceMobx } from '../../../new_fields/util';
+import { DateField } from '../../../fields/DateField';
+import { DataSym, Doc, DocListCast, Field, Opt } from '../../../fields/Doc';
+import { List } from '../../../fields/List';
+import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from '../../../fields/Types';
+import { ImageField } from '../../../fields/URLField';
+import { TraceMobx } from '../../../fields/util';
 import { Utils, setupMoveUpEvents, returnFalse, returnZero, emptyPath, emptyFunction, returnOne } from '../../../Utils';
 import { DocumentType } from '../../documents/DocumentTypes';
 import { ImageUtils } from '../../util/Import & Export/ImageUtils';
@@ -36,12 +36,12 @@ import { CollectionTreeView } from "./CollectionTreeView";
 import './CollectionView.scss';
 import { CollectionViewBaseChrome } from './CollectionViewChromes';
 import { CurrentUserUtils } from '../../util/CurrentUserUtils';
-import { Id } from '../../../new_fields/FieldSymbols';
-import { listSpec } from '../../../new_fields/Schema';
+import { Id } from '../../../fields/FieldSymbols';
+import { listSpec } from '../../../fields/Schema';
 import { Docs } from '../../documents/Documents';
-import { ScriptField, ComputedField } from '../../../new_fields/ScriptField';
+import { ScriptField, ComputedField } from '../../../fields/ScriptField';
 import { InteractionUtils } from '../../util/InteractionUtils';
-import { ObjectField } from '../../../new_fields/ObjectField';
+import { ObjectField } from '../../../fields/ObjectField';
 import CollectionMapView from './CollectionMapView';
 import { CollectionPileView } from './CollectionPileView';
 const higflyout = require("@hig/flyout");
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 62b03bbdc..5dc0b09ac 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -2,11 +2,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import * as React from "react";
-import { Doc, DocListCast } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { List } from "../../../new_fields/List";
-import { listSpec } from "../../../new_fields/Schema";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Doc, DocListCast } from "../../../fields/Doc";
+import { Id } from "../../../fields/FieldSymbols";
+import { List } from "../../../fields/List";
+import { listSpec } from "../../../fields/Schema";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
 import { Utils, emptyFunction, setupMoveUpEvents } from "../../../Utils";
 import { DragManager } from "../../util/DragManager";
 import { undoBatch } from "../../util/UndoManager";
diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx
index 6e4f801c0..649406e6c 100644
--- a/src/client/views/collections/ParentDocumentSelector.tsx
+++ b/src/client/views/collections/ParentDocumentSelector.tsx
@@ -1,12 +1,12 @@
 import * as React from "react";
 import './ParentDocumentSelector.scss';
-import { Doc } from "../../../new_fields/Doc";
+import { Doc } from "../../../fields/Doc";
 import { observer } from "mobx-react";
 import { observable, action, runInAction, trace, computed, reaction, IReactionDisposer } from "mobx";
-import { Id } from "../../../new_fields/FieldSymbols";
+import { Id } from "../../../fields/FieldSymbols";
 import { SearchUtil } from "../../util/SearchUtil";
 import { CollectionDockingView } from "./CollectionDockingView";
-import { NumCast, StrCast } from "../../../new_fields/Types";
+import { NumCast, StrCast } from "../../../fields/Types";
 import { CollectionViewType } from "./CollectionView";
 import { DocumentButtonBar } from "../DocumentButtonBar";
 import { DocumentManager } from "../../util/DocumentManager";
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 9a864078a..3860ce2d7 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -1,15 +1,15 @@
-import { Doc, Field, FieldResult, WidthSym, HeightSym } from "../../../../new_fields/Doc";
-import { NumCast, StrCast, Cast } from "../../../../new_fields/Types";
+import { Doc, Field, FieldResult, WidthSym, HeightSym } from "../../../../fields/Doc";
+import { NumCast, StrCast, Cast } from "../../../../fields/Types";
 import { ScriptBox } from "../../ScriptBox";
 import { CompileScript } from "../../../util/Scripting";
-import { ScriptField } from "../../../../new_fields/ScriptField";
+import { ScriptField } from "../../../../fields/ScriptField";
 import { OverlayView, OverlayElementOptions } from "../../OverlayView";
 import { emptyFunction, aggregateBounds } from "../../../../Utils";
 import React = require("react");
-import { Id, ToString } from "../../../../new_fields/FieldSymbols";
-import { ObjectField } from "../../../../new_fields/ObjectField";
-import { RefField } from "../../../../new_fields/RefField";
-import { listSpec } from "../../../../new_fields/Schema";
+import { Id, ToString } from "../../../../fields/FieldSymbols";
+import { ObjectField } from "../../../../fields/ObjectField";
+import { RefField } from "../../../../fields/RefField";
+import { listSpec } from "../../../../fields/Schema";
 
 export interface ViewDefBounds {
     type: string;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index ba71aff32..f3fc04752 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -1,5 +1,5 @@
 import { observer } from "mobx-react";
-import { Doc } from "../../../../new_fields/Doc";
+import { Doc } from "../../../../fields/Doc";
 import { Utils } from '../../../../Utils';
 import { DocumentView } from "../../nodes/DocumentView";
 import "./CollectionFreeFormLinkView.scss";
@@ -7,8 +7,8 @@ import React = require("react");
 import v5 = require("uuid/v5");
 import { DocumentType } from "../../../documents/DocumentTypes";
 import { observable, action, reaction, IReactionDisposer } from "mobx";
-import { StrCast, Cast } from "../../../../new_fields/Types";
-import { Id } from "../../../../new_fields/FieldSymbols";
+import { StrCast, Cast } from "../../../../fields/Types";
+import { Id } from "../../../../fields/FieldSymbols";
 import { SnappingManager } from "../../../util/SnappingManager";
 
 export interface CollectionFreeFormLinkViewProps {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index 1208fb324..ae81b4b36 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -1,7 +1,7 @@
 import { computed } from "mobx";
 import { observer } from "mobx-react";
-import { Doc } from "../../../../new_fields/Doc";
-import { Id } from "../../../../new_fields/FieldSymbols";
+import { Doc } from "../../../../fields/Doc";
+import { Id } from "../../../../fields/FieldSymbols";
 import { DocumentManager } from "../../../util/DocumentManager";
 import { DocumentView } from "../../nodes/DocumentView";
 import "./CollectionFreeFormLinksView.scss";
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
index 9a5b2c27c..548ad78a5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
@@ -1,16 +1,16 @@
 import { observer } from "mobx-react";
 import * as mobxUtils from 'mobx-utils';
-import CursorField from "../../../../new_fields/CursorField";
-import { listSpec } from "../../../../new_fields/Schema";
-import { Cast } from "../../../../new_fields/Types";
+import CursorField from "../../../../fields/CursorField";
+import { listSpec } from "../../../../fields/Schema";
+import { Cast } from "../../../../fields/Types";
 import { CurrentUserUtils } from "../../../util/CurrentUserUtils";
 import { CollectionViewProps } from "../CollectionSubView";
 import "./CollectionFreeFormView.scss";
 import React = require("react");
 import v5 = require("uuid/v5");
 import { computed } from "mobx";
-import { FieldResult } from "../../../../new_fields/Doc";
-import { List } from "../../../../new_fields/List";
+import { FieldResult } from "../../../../fields/Doc";
+import { List } from "../../../../fields/List";
 
 @observer
 export class CollectionFreeFormRemoteCursors extends React.Component<CollectionViewProps> {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 6c4660c39..fb8bd25da 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -4,16 +4,16 @@ import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrows
 import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, _allowStateChangesInsideComputed } from "mobx";
 import { observer } from "mobx-react";
 import { computedFn } from "mobx-utils";
-import { Doc, HeightSym, Opt, WidthSym, DocListCast } from "../../../../new_fields/Doc";
-import { documentSchema, collectionSchema } from "../../../../new_fields/documentSchemas";
-import { Id } from "../../../../new_fields/FieldSymbols";
-import { InkData, InkField, InkTool, PointData } from "../../../../new_fields/InkField";
-import { List } from "../../../../new_fields/List";
-import { RichTextField } from "../../../../new_fields/RichTextField";
-import { createSchema, listSpec, makeInterface } from "../../../../new_fields/Schema";
-import { ScriptField } from "../../../../new_fields/ScriptField";
-import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../new_fields/Types";
-import { TraceMobx } from "../../../../new_fields/util";
+import { Doc, HeightSym, Opt, WidthSym, DocListCast } from "../../../../fields/Doc";
+import { documentSchema, collectionSchema } from "../../../../fields/documentSchemas";
+import { Id } from "../../../../fields/FieldSymbols";
+import { InkData, InkField, InkTool, PointData } from "../../../../fields/InkField";
+import { List } from "../../../../fields/List";
+import { RichTextField } from "../../../../fields/RichTextField";
+import { createSchema, listSpec, makeInterface } from "../../../../fields/Schema";
+import { ScriptField } from "../../../../fields/ScriptField";
+import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types";
+import { TraceMobx } from "../../../../fields/util";
 import { GestureUtils } from "../../../../pen-gestures/GestureUtils";
 import { aggregateBounds, intersectRect, returnOne, Utils, returnZero, returnFalse } from "../../../../Utils";
 import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
@@ -1034,8 +1034,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         const { newPool, computedElementData } = this.doInternalLayoutComputation;
         const array = Array.from(newPool.entries());
         runInAction(() => {
-            for (let i = 0; i < array.length; i++) {
-                const entry = array[i];
+            for (const entry of array) {
                 const lastPos = this._cachedPool.get(entry[0]); // last computed pos
                 const newPos = entry[1];
                 if (!lastPos || newPos.x !== lastPos.x || newPos.y !== lastPos.y || newPos.z !== lastPos.z || newPos.zIndex !== lastPos.zIndex) {
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 8e20b39d2..04d37934e 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -1,11 +1,11 @@
 import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, Opt } from "../../../../new_fields/Doc";
-import { InkData, InkField } from "../../../../new_fields/InkField";
-import { List } from "../../../../new_fields/List";
-import { RichTextField } from "../../../../new_fields/RichTextField";
-import { SchemaHeaderField } from "../../../../new_fields/SchemaHeaderField";
-import { Cast, FieldValue, NumCast, StrCast } from "../../../../new_fields/Types";
+import { Doc, Opt } from "../../../../fields/Doc";
+import { InkData, InkField } from "../../../../fields/InkField";
+import { List } from "../../../../fields/List";
+import { RichTextField } from "../../../../fields/RichTextField";
+import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField";
+import { Cast, FieldValue, NumCast, StrCast } from "../../../../fields/Types";
 import { Utils } from "../../../../Utils";
 import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
 import { Docs, DocumentOptions, DocUtils } from "../../../documents/Documents";
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index a09124304..c0e1a0232 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -1,10 +1,10 @@
 import { action, computed } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from "react";
-import { Doc } from '../../../../new_fields/Doc';
-import { documentSchema } from '../../../../new_fields/documentSchemas';
-import { makeInterface } from '../../../../new_fields/Schema';
-import { BoolCast, NumCast, ScriptCast, StrCast, Cast } from '../../../../new_fields/Types';
+import { Doc } from '../../../../fields/Doc';
+import { documentSchema } from '../../../../fields/documentSchemas';
+import { makeInterface } from '../../../../fields/Schema';
+import { BoolCast, NumCast, ScriptCast, StrCast, Cast } from '../../../../fields/Types';
 import { DragManager, dropActionType } from '../../../util/DragManager';
 import { Transform } from '../../../util/Transform';
 import { undoBatch } from '../../../util/UndoManager';
@@ -13,7 +13,7 @@ import { CollectionSubView } from '../CollectionSubView';
 import "./collectionMulticolumnView.scss";
 import ResizeBar from './MulticolumnResizer';
 import WidthLabel from './MulticolumnWidthLabel';
-import { List } from '../../../../new_fields/List';
+import { List } from '../../../../fields/List';
 import { returnZero, returnFalse, returnOne } from '../../../../Utils';
 
 type MulticolumnDocument = makeInterface<[typeof documentSchema]>;
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 4326723b1..602246d07 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -1,10 +1,10 @@
 import { observer } from 'mobx-react';
-import { makeInterface } from '../../../../new_fields/Schema';
-import { documentSchema } from '../../../../new_fields/documentSchemas';
+import { makeInterface } from '../../../../fields/Schema';
+import { documentSchema } from '../../../../fields/documentSchemas';
 import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView';
 import * as React from "react";
-import { Doc } from '../../../../new_fields/Doc';
-import { NumCast, StrCast, BoolCast, ScriptCast } from '../../../../new_fields/Types';
+import { Doc } from '../../../../fields/Doc';
+import { NumCast, StrCast, BoolCast, ScriptCast } from '../../../../fields/Types';
 import { ContentFittingDocumentView } from '../../nodes/ContentFittingDocumentView';
 import { Utils, returnZero, returnFalse, returnOne } from '../../../../Utils';
 import "./collectionMultirowView.scss";
@@ -14,7 +14,7 @@ import HeightLabel from './MultirowHeightLabel';
 import ResizeBar from './MultirowResizer';
 import { undoBatch } from '../../../util/UndoManager';
 import { DragManager, dropActionType } from '../../../util/DragManager';
-import { List } from '../../../../new_fields/List';
+import { List } from '../../../../fields/List';
 
 type MultirowDocument = makeInterface<[typeof documentSchema]>;
 const MultirowDocument = makeInterface(documentSchema);
diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
index a24eb1631..734915a93 100644
--- a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
@@ -1,8 +1,8 @@
 import * as React from "react";
 import { observer } from "mobx-react";
 import { observable, action } from "mobx";
-import { Doc } from "../../../../new_fields/Doc";
-import { NumCast, StrCast } from "../../../../new_fields/Types";
+import { Doc } from "../../../../fields/Doc";
+import { NumCast, StrCast } from "../../../../fields/Types";
 import { DimUnit } from "./CollectionMulticolumnView";
 import { UndoManager } from "../../../util/UndoManager";
 
diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
index 5b2054428..9985a9fba 100644
--- a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
@@ -1,8 +1,8 @@
 import * as React from "react";
 import { observer } from "mobx-react";
 import { computed } from "mobx";
-import { Doc } from "../../../../new_fields/Doc";
-import { NumCast, StrCast, BoolCast } from "../../../../new_fields/Types";
+import { Doc } from "../../../../fields/Doc";
+import { NumCast, StrCast, BoolCast } from "../../../../fields/Types";
 import { EditableView } from "../../EditableView";
 import { DimUnit } from "./CollectionMulticolumnView";
 
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
index 899577fd5..aa5439fa4 100644
--- a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
@@ -1,8 +1,8 @@
 import * as React from "react";
 import { observer } from "mobx-react";
 import { computed } from "mobx";
-import { Doc } from "../../../../new_fields/Doc";
-import { NumCast, StrCast, BoolCast } from "../../../../new_fields/Types";
+import { Doc } from "../../../../fields/Doc";
+import { NumCast, StrCast, BoolCast } from "../../../../fields/Types";
 import { EditableView } from "../../EditableView";
 import { DimUnit } from "./CollectionMultirowView";
 
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
index 5f00b18b9..d0bc4d01c 100644
--- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
@@ -1,8 +1,8 @@
 import * as React from "react";
 import { observer } from "mobx-react";
 import { observable, action } from "mobx";
-import { Doc } from "../../../../new_fields/Doc";
-import { NumCast, StrCast } from "../../../../new_fields/Types";
+import { Doc } from "../../../../fields/Doc";
+import { NumCast, StrCast } from "../../../../fields/Types";
 import { DimUnit } from "./CollectionMultirowView";
 import { UndoManager } from "../../../util/UndoManager";
 
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index b7f3dd995..5fb4cf3c6 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -3,8 +3,8 @@ import { faArrowLeft, faCog, faEllipsisV, faExchangeAlt, faPlus, faTable, faTime
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, observable } from "mobx";
 import { observer } from "mobx-react";
-import { Doc } from "../../../new_fields/Doc";
-import { StrCast } from "../../../new_fields/Types";
+import { Doc } from "../../../fields/Doc";
+import { StrCast } from "../../../fields/Types";
 import { Utils } from "../../../Utils";
 import { LinkManager } from "../../util/LinkManager";
 import './LinkEditor.scss';
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index b768eacc3..786d6be47 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -4,7 +4,7 @@ import { DocumentView } from "../nodes/DocumentView";
 import { LinkEditor } from "./LinkEditor";
 import './LinkMenu.scss';
 import React = require("react");
-import { Doc } from "../../../new_fields/Doc";
+import { Doc } from "../../../fields/Doc";
 import { LinkManager } from "../../util/LinkManager";
 import { LinkMenuGroup } from "./LinkMenuGroup";
 import { faTrash } from '@fortawesome/free-solid-svg-icons';
diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx
index c97e1062d..89deb3a55 100644
--- a/src/client/views/linking/LinkMenuGroup.tsx
+++ b/src/client/views/linking/LinkMenuGroup.tsx
@@ -1,9 +1,9 @@
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action } from "mobx";
 import { observer } from "mobx-react";
-import { Doc } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
+import { Doc } from "../../../fields/Doc";
+import { Id } from "../../../fields/FieldSymbols";
+import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
 import { Docs } from "../../documents/Documents";
 import { DragManager, SetupDrag } from "../../util/DragManager";
 import { LinkManager } from "../../util/LinkManager";
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index b0c61cb04..17cd33241 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -3,8 +3,8 @@ import { faArrowRight, faChevronDown, faChevronUp, faEdit, faEye, faTimes } from
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, observable } from 'mobx';
 import { observer } from "mobx-react";
-import { Doc, DocListCast } from '../../../new_fields/Doc';
-import { Cast, StrCast } from '../../../new_fields/Types';
+import { Doc, DocListCast } from '../../../fields/Doc';
+import { Cast, StrCast } from '../../../fields/Types';
 import { DragManager } from '../../util/DragManager';
 import { LinkManager } from '../../util/LinkManager';
 import { ContextMenu } from '../ContextMenu';
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 1c5e13620..1a935d9b0 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -2,23 +2,23 @@ import React = require("react");
 import { FieldViewProps, FieldView } from './FieldView';
 import { observer } from "mobx-react";
 import "./AudioBox.scss";
-import { Cast, DateCast, NumCast } from "../../../new_fields/Types";
-import { AudioField, nullAudio } from "../../../new_fields/URLField";
+import { Cast, DateCast, NumCast } from "../../../fields/Types";
+import { AudioField, nullAudio } from "../../../fields/URLField";
 import { ViewBoxBaseComponent } from "../DocComponent";
-import { makeInterface, createSchema } from "../../../new_fields/Schema";
-import { documentSchema } from "../../../new_fields/documentSchemas";
+import { makeInterface, createSchema } from "../../../fields/Schema";
+import { documentSchema } from "../../../fields/documentSchemas";
 import { Utils, returnTrue, emptyFunction, returnOne, returnTransparent, returnFalse, returnZero } from "../../../Utils";
 import { runInAction, observable, reaction, IReactionDisposer, computed, action } from "mobx";
-import { DateField } from "../../../new_fields/DateField";
+import { DateField } from "../../../fields/DateField";
 import { SelectionManager } from "../../util/SelectionManager";
-import { Doc, DocListCast } from "../../../new_fields/Doc";
+import { Doc, DocListCast } from "../../../fields/Doc";
 import { ContextMenuProps } from "../ContextMenuItem";
 import { ContextMenu } from "../ContextMenu";
-import { Id } from "../../../new_fields/FieldSymbols";
+import { Id } from "../../../fields/FieldSymbols";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { DocumentView } from "./DocumentView";
 import { Docs, DocUtils } from "../../documents/Documents";
-import { ComputedField } from "../../../new_fields/ScriptField";
+import { ComputedField } from "../../../fields/ScriptField";
 import { Networking } from "../../Network";
 import { LinkAnchorBox } from "./LinkAnchorBox";
 
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index cdbe506a5..5d6e587d9 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,14 +1,14 @@
 import { computed, IReactionDisposer, observable, reaction, trace } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, HeightSym, WidthSym } from "../../../new_fields/Doc";
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Doc, HeightSym, WidthSym } from "../../../fields/Doc";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
 import { Transform } from "../../util/Transform";
 import { DocComponent } from "../DocComponent";
 import "./CollectionFreeFormDocumentView.scss";
 import { DocumentView, DocumentViewProps } from "./DocumentView";
 import React = require("react");
-import { Document } from "../../../new_fields/documentSchemas";
-import { TraceMobx } from "../../../new_fields/util";
+import { Document } from "../../../fields/documentSchemas";
+import { TraceMobx } from "../../../fields/util";
 import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
 
 export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx
index bc84204b9..bef6609c4 100644
--- a/src/client/views/nodes/ColorBox.tsx
+++ b/src/client/views/nodes/ColorBox.tsx
@@ -1,9 +1,9 @@
 import React = require("react");
 import { observer } from "mobx-react";
 import { SketchPicker } from 'react-color';
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { makeInterface } from "../../../new_fields/Schema";
-import { StrCast } from "../../../new_fields/Types";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface } from "../../../fields/Schema";
+import { StrCast } from "../../../fields/Types";
 import { CurrentUserUtils } from "../../util/CurrentUserUtils";
 import { SelectionManager } from "../../util/SelectionManager";
 import { ViewBoxBaseComponent } from "../DocComponent";
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index 1c6250b94..a90b4668e 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -2,9 +2,9 @@ import React = require("react");
 import { computed } from "mobx";
 import { observer } from "mobx-react";
 import "react-table/react-table.css";
-import { Doc, Opt, WidthSym, HeightSym } from "../../../new_fields/Doc";
-import { NumCast, StrCast, Cast } from "../../../new_fields/Types";
-import { TraceMobx } from "../../../new_fields/util";
+import { Doc, Opt, WidthSym, HeightSym } from "../../../fields/Doc";
+import { NumCast, StrCast, Cast } from "../../../fields/Types";
+import { TraceMobx } from "../../../fields/util";
 import { emptyFunction, returnOne } from "../../../Utils";
 import '../DocumentDecorations.scss';
 import { DocumentView, DocumentViewProps } from "../nodes/DocumentView";
diff --git a/src/client/views/nodes/DocHolderBox.tsx b/src/client/views/nodes/DocHolderBox.tsx
index af8dc704c..0c5239d66 100644
--- a/src/client/views/nodes/DocHolderBox.tsx
+++ b/src/client/views/nodes/DocHolderBox.tsx
@@ -1,12 +1,12 @@
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, IReactionDisposer, reaction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, Field } from "../../../new_fields/Doc";
-import { collectionSchema, documentSchema } from "../../../new_fields/documentSchemas";
-import { makeInterface, listSpec } from "../../../new_fields/Schema";
-import { ComputedField } from "../../../new_fields/ScriptField";
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { TraceMobx } from "../../../new_fields/util";
+import { Doc, Field } from "../../../fields/Doc";
+import { collectionSchema, documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface, listSpec } from "../../../fields/Schema";
+import { ComputedField } from "../../../fields/ScriptField";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
+import { TraceMobx } from "../../../fields/util";
 import { emptyPath, returnFalse, returnOne, returnZero } from "../../../Utils";
 import { DocumentType } from "../../documents/DocumentTypes";
 import { DragManager } from "../../util/DragManager";
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 2fc82e524..f4785bb0c 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -1,7 +1,7 @@
 import { computed } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, Opt, Field } from "../../../new_fields/Doc";
-import { Cast, StrCast, NumCast } from "../../../new_fields/Types";
+import { Doc, Opt, Field } from "../../../fields/Doc";
+import { Cast, StrCast, NumCast } from "../../../fields/Types";
 import { OmitKeys, Without, emptyPath } from "../../../Utils";
 import DirectoryImportBox from "../../util/Import & Export/DirectoryImportBox";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
@@ -35,8 +35,8 @@ import { WebBox } from "./WebBox";
 import { InkingStroke } from "../InkingStroke";
 import React = require("react");
 import { RecommendationsBox } from "../RecommendationsBox";
-import { TraceMobx } from "../../../new_fields/util";
-import { ScriptField } from "../../../new_fields/ScriptField";
+import { TraceMobx } from "../../../fields/util";
+import { ScriptField } from "../../../fields/ScriptField";
 import XRegExp = require("xregexp");
 
 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
diff --git a/src/client/views/nodes/DocumentIcon.tsx b/src/client/views/nodes/DocumentIcon.tsx
index f56f5e829..fb54f18e8 100644
--- a/src/client/views/nodes/DocumentIcon.tsx
+++ b/src/client/views/nodes/DocumentIcon.tsx
@@ -3,7 +3,7 @@ import * as React from "react";
 import { DocumentView } from "./DocumentView";
 import { DocumentManager } from "../../util/DocumentManager";
 import { Transformer, Scripting, ts } from "../../util/Scripting";
-import { Field } from "../../../new_fields/Doc";
+import { Field } from "../../../fields/Doc";
 
 @observer
 export class DocumentIcon extends React.Component<{ view: DocumentView, index: number }> {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index d821bb8ac..340fa06a8 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -4,16 +4,16 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import * as rp from "request-promise";
-import { Doc, DocListCast, HeightSym, Opt, WidthSym, DataSym } from "../../../new_fields/Doc";
-import { Document } from '../../../new_fields/documentSchemas';
-import { Id } from '../../../new_fields/FieldSymbols';
-import { InkTool } from '../../../new_fields/InkField';
-import { listSpec } from "../../../new_fields/Schema";
-import { SchemaHeaderField } from '../../../new_fields/SchemaHeaderField';
-import { ScriptField } from '../../../new_fields/ScriptField';
-import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { ImageField } from '../../../new_fields/URLField';
-import { TraceMobx } from '../../../new_fields/util';
+import { Doc, DocListCast, HeightSym, Opt, WidthSym, DataSym } from "../../../fields/Doc";
+import { Document } from '../../../fields/documentSchemas';
+import { Id } from '../../../fields/FieldSymbols';
+import { InkTool } from '../../../fields/InkField';
+import { listSpec } from "../../../fields/Schema";
+import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
+import { ScriptField } from '../../../fields/ScriptField';
+import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
+import { ImageField } from '../../../fields/URLField';
+import { TraceMobx } from '../../../fields/util';
 import { GestureUtils } from '../../../pen-gestures/GestureUtils';
 import { emptyFunction, OmitKeys, returnOne, returnTransparent, Utils, emptyPath } from "../../../Utils";
 import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils';
diff --git a/src/client/views/nodes/FaceRectangles.tsx b/src/client/views/nodes/FaceRectangles.tsx
index 3c7f1f206..92ca276cb 100644
--- a/src/client/views/nodes/FaceRectangles.tsx
+++ b/src/client/views/nodes/FaceRectangles.tsx
@@ -1,8 +1,8 @@
 import React = require("react");
-import { Doc, DocListCast } from "../../../new_fields/Doc";
-import { Cast, NumCast } from "../../../new_fields/Types";
+import { Doc, DocListCast } from "../../../fields/Doc";
+import { Cast, NumCast } from "../../../fields/Types";
 import { observer } from "mobx-react";
-import { Id } from "../../../new_fields/FieldSymbols";
+import { Id } from "../../../fields/FieldSymbols";
 import FaceRectangle from "./FaceRectangle";
 
 interface FaceRectanglesProps {
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 2ab0a416d..e9dc43bd8 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -1,11 +1,11 @@
 import React = require("react");
 import { computed } from "mobx";
 import { observer } from "mobx-react";
-import { DateField } from "../../../new_fields/DateField";
-import { Doc, FieldResult, Opt, Field } from "../../../new_fields/Doc";
-import { List } from "../../../new_fields/List";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { AudioField, VideoField } from "../../../new_fields/URLField";
+import { DateField } from "../../../fields/DateField";
+import { Doc, FieldResult, Opt, Field } from "../../../fields/Doc";
+import { List } from "../../../fields/List";
+import { ScriptField } from "../../../fields/ScriptField";
+import { AudioField, VideoField } from "../../../fields/URLField";
 import { Transform } from "../../util/Transform";
 import { CollectionView } from "../collections/CollectionView";
 import { AudioBox } from "./AudioBox";
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index 0d597b3a8..cf0b16c7c 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -1,16 +1,16 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { createSchema, makeInterface } from '../../../new_fields/Schema';
+import { createSchema, makeInterface } from '../../../fields/Schema';
 import { DocComponent } from '../DocComponent';
 import './FontIconBox.scss';
 import { FieldView, FieldViewProps } from './FieldView';
-import { StrCast, Cast } from '../../../new_fields/Types';
+import { StrCast, Cast } from '../../../fields/Types';
 import { Utils } from "../../../Utils";
 import { runInAction, observable, reaction, IReactionDisposer } from 'mobx';
-import { Doc } from '../../../new_fields/Doc';
+import { Doc } from '../../../fields/Doc';
 import { ContextMenu } from '../ContextMenu';
-import { ScriptField } from '../../../new_fields/ScriptField';
+import { ScriptField } from '../../../fields/ScriptField';
 const FontIconSchema = createSchema({
     icon: "string"
 });
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index aaebceaa2..47e7607d6 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -4,16 +4,16 @@ import { faAsterisk, faBrain, faFileAudio, faImage, faPaintBrush } from '@fortaw
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable, runInAction } from 'mobx';
 import { observer } from "mobx-react";
-import { DataSym, Doc, DocListCast, HeightSym, WidthSym } from '../../../new_fields/Doc';
-import { documentSchema } from '../../../new_fields/documentSchemas';
-import { Id } from '../../../new_fields/FieldSymbols';
-import { List } from '../../../new_fields/List';
-import { ObjectField } from '../../../new_fields/ObjectField';
-import { createSchema, listSpec, makeInterface } from '../../../new_fields/Schema';
-import { ComputedField } from '../../../new_fields/ScriptField';
-import { Cast, NumCast, StrCast } from '../../../new_fields/Types';
-import { AudioField, ImageField } from '../../../new_fields/URLField';
-import { TraceMobx } from '../../../new_fields/util';
+import { DataSym, Doc, DocListCast, HeightSym, WidthSym } from '../../../fields/Doc';
+import { documentSchema } from '../../../fields/documentSchemas';
+import { Id } from '../../../fields/FieldSymbols';
+import { List } from '../../../fields/List';
+import { ObjectField } from '../../../fields/ObjectField';
+import { createSchema, listSpec, makeInterface } from '../../../fields/Schema';
+import { ComputedField } from '../../../fields/ScriptField';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { AudioField, ImageField } from '../../../fields/URLField';
+import { TraceMobx } from '../../../fields/util';
 import { emptyFunction, returnOne, Utils, returnZero } from '../../../Utils';
 import { CognitiveServices, Confidence, Service, Tag } from '../../cognitive_services/CognitiveServices';
 import { Docs } from '../../documents/Documents';
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 39d7109b1..e983852ea 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -1,13 +1,13 @@
 
 import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, Field, FieldResult } from "../../../new_fields/Doc";
-import { List } from "../../../new_fields/List";
-import { RichTextField } from "../../../new_fields/RichTextField";
-import { listSpec } from "../../../new_fields/Schema";
-import { ComputedField, ScriptField } from "../../../new_fields/ScriptField";
-import { Cast, FieldValue, NumCast } from "../../../new_fields/Types";
-import { ImageField } from "../../../new_fields/URLField";
+import { Doc, Field, FieldResult } from "../../../fields/Doc";
+import { List } from "../../../fields/List";
+import { RichTextField } from "../../../fields/RichTextField";
+import { listSpec } from "../../../fields/Schema";
+import { ComputedField, ScriptField } from "../../../fields/ScriptField";
+import { Cast, FieldValue, NumCast } from "../../../fields/Types";
+import { ImageField } from "../../../fields/URLField";
 import { Docs } from "../../documents/Documents";
 import { SetupDrag } from "../../util/DragManager";
 import { CompiledScript, CompileScript, ScriptOptions } from "../../util/Scripting";
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 6dc4ae578..956d6556b 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -1,6 +1,6 @@
 import { action, observable } from 'mobx';
 import { observer } from "mobx-react";
-import { Doc, Field, Opt } from '../../../new_fields/Doc';
+import { Doc, Field, Opt } from '../../../fields/Doc';
 import { emptyFunction, returnFalse, returnOne, returnZero } from '../../../Utils';
 import { Docs } from '../../documents/Documents';
 import { Transform } from '../../util/Transform';
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index ac27640bd..2d27ec441 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -3,11 +3,11 @@ import { faEdit } from '@fortawesome/free-regular-svg-icons';
 import { action } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { Doc, DocListCast } from '../../../new_fields/Doc';
-import { documentSchema } from '../../../new_fields/documentSchemas';
-import { List } from '../../../new_fields/List';
-import { createSchema, listSpec, makeInterface } from '../../../new_fields/Schema';
-import { Cast, NumCast, StrCast } from '../../../new_fields/Types';
+import { Doc, DocListCast } from '../../../fields/Doc';
+import { documentSchema } from '../../../fields/documentSchemas';
+import { List } from '../../../fields/List';
+import { createSchema, listSpec, makeInterface } from '../../../fields/Schema';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
 import { DragManager } from '../../util/DragManager';
 import { undoBatch } from '../../util/UndoManager';
 import { ContextMenu } from '../ContextMenu';
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index bc36e056e..098aa58e9 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -1,9 +1,9 @@
 import { action, observable } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast } from "../../../new_fields/Doc";
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { makeInterface } from "../../../new_fields/Schema";
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Doc, DocListCast } from "../../../fields/Doc";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface } from "../../../fields/Schema";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
 import { Utils, setupMoveUpEvents, emptyFunction } from '../../../Utils';
 import { DocumentManager } from "../../util/DocumentManager";
 import { DragManager } from "../../util/DragManager";
@@ -16,7 +16,7 @@ import { ContextMenu } from "../ContextMenu";
 import { LinkEditor } from "../linking/LinkEditor";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { SelectionManager } from "../../util/SelectionManager";
-import { TraceMobx } from "../../../new_fields/util";
+import { TraceMobx } from "../../../fields/util";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 740f2ef04..3f942e87b 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -1,13 +1,13 @@
 import React = require("react");
 import { observer } from "mobx-react";
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { makeInterface, listSpec } from "../../../new_fields/Schema";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface, listSpec } from "../../../fields/Schema";
 import { returnFalse, returnZero } from "../../../Utils";
 import { CollectionTreeView } from "../collections/CollectionTreeView";
 import { ViewBoxBaseComponent } from "../DocComponent";
 import { FieldView, FieldViewProps } from './FieldView';
 import "./LinkBox.scss";
-import { Cast } from "../../../new_fields/Types";
+import { Cast } from "../../../fields/Types";
 
 type LinkDocument = makeInterface<[typeof documentSchema]>;
 const LinkDocument = makeInterface(documentSchema);
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 3712c648e..493f23dc4 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -3,11 +3,11 @@ import { action, observable, runInAction, reaction, IReactionDisposer, trace, un
 import { observer } from "mobx-react";
 import * as Pdfjs from "pdfjs-dist";
 import "pdfjs-dist/web/pdf_viewer.css";
-import { Opt, WidthSym, Doc, HeightSym } from "../../../new_fields/Doc";
-import { makeInterface } from "../../../new_fields/Schema";
-import { ScriptField } from '../../../new_fields/ScriptField';
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { PdfField, URLField } from "../../../new_fields/URLField";
+import { Opt, WidthSym, Doc, HeightSym } from "../../../fields/Doc";
+import { makeInterface } from "../../../fields/Schema";
+import { ScriptField } from '../../../fields/ScriptField';
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
+import { PdfField, URLField } from "../../../fields/URLField";
 import { Utils } from '../../../Utils';
 import { undoBatch } from '../../util/UndoManager';
 import { panZoomSchema } from '../collections/collectionFreeForm/CollectionFreeFormView';
@@ -20,7 +20,7 @@ import { pageSchema } from "./ImageBox";
 import { KeyCodes } from '../../util/KeyCodes';
 import "./PDFBox.scss";
 import React = require("react");
-import { documentSchema } from '../../../new_fields/documentSchemas';
+import { documentSchema } from '../../../fields/documentSchemas';
 
 type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>;
 const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema);
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 42552ec73..342a8a215 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -2,11 +2,11 @@ import React = require("react");
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast, DocCastAsync } from "../../../new_fields/Doc";
-import { InkTool } from "../../../new_fields/InkField";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Doc, DocListCast, DocCastAsync } from "../../../fields/Doc";
+import { InkTool } from "../../../fields/InkField";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
 import { returnFalse } from "../../../Utils";
-import { documentSchema } from "../../../new_fields/documentSchemas";
+import { documentSchema } from "../../../fields/documentSchemas";
 import { DocumentManager } from "../../util/DocumentManager";
 import { undoBatch } from "../../util/UndoManager";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
@@ -15,11 +15,11 @@ import { InkingControl } from "../InkingControl";
 import { FieldView, FieldViewProps } from './FieldView';
 import "./PresBox.scss";
 import { ViewBoxBaseComponent } from "../DocComponent";
-import { makeInterface } from "../../../new_fields/Schema";
-import { List } from "../../../new_fields/List";
+import { makeInterface } from "../../../fields/Schema";
+import { List } from "../../../fields/List";
 import { Docs } from "../../documents/Documents";
-import { PrefetchProxy } from "../../../new_fields/Proxy";
-import { ScriptField } from "../../../new_fields/ScriptField";
+import { PrefetchProxy } from "../../../fields/Proxy";
+import { ScriptField } from "../../../fields/ScriptField";
 import { Scripting } from "../../util/Scripting";
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
diff --git a/src/client/views/nodes/QueryBox.tsx b/src/client/views/nodes/QueryBox.tsx
index 2a21a380d..0fff0b57f 100644
--- a/src/client/views/nodes/QueryBox.tsx
+++ b/src/client/views/nodes/QueryBox.tsx
@@ -1,15 +1,15 @@
 import React = require("react");
 import { IReactionDisposer } from "mobx";
 import { observer } from "mobx-react";
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { Id } from '../../../new_fields/FieldSymbols';
-import { makeInterface, listSpec } from "../../../new_fields/Schema";
-import { StrCast, Cast } from "../../../new_fields/Types";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { Id } from '../../../fields/FieldSymbols';
+import { makeInterface, listSpec } from "../../../fields/Schema";
+import { StrCast, Cast } from "../../../fields/Types";
 import { ViewBoxAnnotatableComponent } from '../DocComponent';
 import { SearchBox } from "../search/SearchBox";
 import { FieldView, FieldViewProps } from './FieldView';
 import "./QueryBox.scss";
-import { List } from "../../../new_fields/List";
+import { List } from "../../../fields/List";
 import { SnappingManager } from "../../util/SnappingManager";
 
 type QueryDocument = makeInterface<[typeof documentSchema]>;
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index a0ecc9ff5..5d4af2d77 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -5,10 +5,10 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, IReactionDisposer, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import * as rp from 'request-promise';
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { makeInterface } from "../../../new_fields/Schema";
-import { Cast, NumCast } from "../../../new_fields/Types";
-import { VideoField } from "../../../new_fields/URLField";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface } from "../../../fields/Schema";
+import { Cast, NumCast } from "../../../fields/Types";
+import { VideoField } from "../../../fields/URLField";
 import { emptyFunction, returnFalse, returnOne, Utils, returnZero } from "../../../Utils";
 import { Docs, DocUtils } from "../../documents/Documents";
 import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx
index c607d6614..0944edf60 100644
--- a/src/client/views/nodes/ScriptingBox.tsx
+++ b/src/client/views/nodes/ScriptingBox.tsx
@@ -1,10 +1,10 @@
 import { action, observable, computed } from "mobx";
 import { observer } from "mobx-react";
 import * as React from "react";
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { createSchema, makeInterface, listSpec } from "../../../new_fields/Schema";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { StrCast, ScriptCast, Cast } from "../../../new_fields/Types";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { createSchema, makeInterface, listSpec } from "../../../fields/Schema";
+import { ScriptField } from "../../../fields/ScriptField";
+import { StrCast, ScriptCast, Cast } from "../../../fields/Types";
 import { InteractionUtils } from "../../util/InteractionUtils";
 import { CompileScript, isCompileError, ScriptParam } from "../../util/Scripting";
 import { ViewBoxAnnotatableComponent } from "../DocComponent";
@@ -13,7 +13,7 @@ import { FieldView, FieldViewProps } from "../nodes/FieldView";
 import "./ScriptingBox.scss";
 import { OverlayView } from "../OverlayView";
 import { DocumentIconContainer } from "./DocumentIcon";
-import { List } from "../../../new_fields/List";
+import { List } from "../../../fields/List";
 
 const ScriptingSchema = createSchema({});
 type ScriptingDocument = makeInterface<[typeof ScriptingSchema, typeof documentSchema]>;
diff --git a/src/client/views/nodes/SliderBox.tsx b/src/client/views/nodes/SliderBox.tsx
index cb2526769..9a1aefba9 100644
--- a/src/client/views/nodes/SliderBox.tsx
+++ b/src/client/views/nodes/SliderBox.tsx
@@ -4,10 +4,10 @@ import { runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { Handles, Rail, Slider, Ticks, Tracks } from 'react-compound-slider';
-import { documentSchema } from '../../../new_fields/documentSchemas';
-import { createSchema, makeInterface } from '../../../new_fields/Schema';
-import { ScriptField } from '../../../new_fields/ScriptField';
-import { Cast, NumCast, StrCast } from '../../../new_fields/Types';
+import { documentSchema } from '../../../fields/documentSchemas';
+import { createSchema, makeInterface } from '../../../fields/Schema';
+import { ScriptField } from '../../../fields/ScriptField';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
 import { ContextMenu } from '../ContextMenu';
 import { ContextMenuProps } from '../ContextMenuItem';
 import { ViewBoxBaseComponent } from '../DocComponent';
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 9602eac52..ccf1f5588 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -5,12 +5,12 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, IReactionDisposer, observable, reaction, runInAction, untracked } from "mobx";
 import { observer } from "mobx-react";
 import * as rp from 'request-promise';
-import { Doc } from "../../../new_fields/Doc";
-import { InkTool } from "../../../new_fields/InkField";
-import { createSchema, makeInterface } from "../../../new_fields/Schema";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { Cast, StrCast } from "../../../new_fields/Types";
-import { VideoField } from "../../../new_fields/URLField";
+import { Doc } from "../../../fields/Doc";
+import { InkTool } from "../../../fields/InkField";
+import { createSchema, makeInterface } from "../../../fields/Schema";
+import { ScriptField } from "../../../fields/ScriptField";
+import { Cast, StrCast } from "../../../fields/Types";
+import { VideoField } from "../../../fields/URLField";
 import { Utils, emptyFunction, returnOne, returnZero } from "../../../Utils";
 import { Docs, DocUtils } from "../../documents/Documents";
 import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
@@ -21,7 +21,7 @@ import { DocumentDecorations } from "../DocumentDecorations";
 import { InkingControl } from "../InkingControl";
 import { FieldView, FieldViewProps } from './FieldView';
 import "./VideoBox.scss";
-import { documentSchema } from "../../../new_fields/documentSchemas";
+import { documentSchema } from "../../../fields/documentSchemas";
 const path = require('path');
 
 export const timeSchema = createSchema({
@@ -337,7 +337,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
     }
 
     @action.bound
-    addDocumentWithTimestamp(doc: Doc|Doc[]): boolean {
+    addDocumentWithTimestamp(doc: Doc | Doc[]): boolean {
         const docs = doc instanceof Doc ? [doc] : doc;
         docs.forEach(doc => {
             const curTime = (this.layoutDoc.currentTimecode || -1);
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 6d4cc1a07..82f05012a 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -2,13 +2,13 @@ import { library } from "@fortawesome/fontawesome-svg-core";
 import { faStickyNote, faPen, faMousePointer } from '@fortawesome/free-solid-svg-icons';
 import { action, computed, observable, trace, IReactionDisposer, reaction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, FieldResult } from "../../../new_fields/Doc";
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { HtmlField } from "../../../new_fields/HtmlField";
-import { InkTool } from "../../../new_fields/InkField";
-import { makeInterface } from "../../../new_fields/Schema";
-import { Cast, NumCast, BoolCast, StrCast } from "../../../new_fields/Types";
-import { WebField } from "../../../new_fields/URLField";
+import { Doc, FieldResult } from "../../../fields/Doc";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { HtmlField } from "../../../fields/HtmlField";
+import { InkTool } from "../../../fields/InkField";
+import { makeInterface } from "../../../fields/Schema";
+import { Cast, NumCast, BoolCast, StrCast } from "../../../fields/Types";
+import { WebField } from "../../../fields/URLField";
 import { Utils, returnOne, emptyFunction, returnZero } from "../../../Utils";
 import { Docs } from "../../documents/Documents";
 import { DragManager } from "../../util/DragManager";
diff --git a/src/client/views/nodes/formattedText/DashDocCommentView.tsx b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
index d94fe7fc6..d56b87ae5 100644
--- a/src/client/views/nodes/formattedText/DashDocCommentView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
@@ -8,14 +8,14 @@ import { EditorState, NodeSelection, Plugin, TextSelection } from "prosemirror-s
 import { StepMap } from "prosemirror-transform";
 import { EditorView } from "prosemirror-view";
 import * as ReactDOM from 'react-dom';
-import { Doc, DocListCast, Field, HeightSym, WidthSym } from "../../../../new_fields/Doc";
-import { Id } from "../../../../new_fields/FieldSymbols";
-import { List } from "../../../../new_fields/List";
-import { ObjectField } from "../../../../new_fields/ObjectField";
-import { listSpec } from "../../../../new_fields/Schema";
-import { SchemaHeaderField } from "../../../../new_fields/SchemaHeaderField";
-import { ComputedField } from "../../../../new_fields/ScriptField";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../../new_fields/Types";
+import { Doc, DocListCast, Field, HeightSym, WidthSym } from "../../../../fields/Doc";
+import { Id } from "../../../../fields/FieldSymbols";
+import { List } from "../../../../fields/List";
+import { ObjectField } from "../../../../fields/ObjectField";
+import { listSpec } from "../../../../fields/Schema";
+import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField";
+import { ComputedField } from "../../../../fields/ScriptField";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types";
 import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils, returnZero } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
 
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 7130fee2b..05e6a5959 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -1,10 +1,10 @@
 import { IReactionDisposer, reaction } from "mobx";
 import { NodeSelection } from "prosemirror-state";
-import { Doc, HeightSym, WidthSym } from "../../../../new_fields/Doc";
-import { Id } from "../../../../new_fields/FieldSymbols";
-import { ObjectField } from "../../../../new_fields/ObjectField";
-import { ComputedField } from "../../../../new_fields/ScriptField";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../../new_fields/Types";
+import { Doc, HeightSym, WidthSym } from "../../../../fields/Doc";
+import { Id } from "../../../../fields/FieldSymbols";
+import { ObjectField } from "../../../../fields/ObjectField";
+import { ComputedField } from "../../../../fields/ScriptField";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types";
 import { emptyFunction, returnEmptyString, returnFalse, Utils, returnZero } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
 import { Docs } from "../../../documents/Documents";
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 3c6841f08..d05e8f1ea 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -1,10 +1,10 @@
 import { IReactionDisposer, observable, runInAction, computed, action } from "mobx";
-import { Doc, DocListCast, Field } from "../../../../new_fields/Doc";
-import { List } from "../../../../new_fields/List";
-import { listSpec } from "../../../../new_fields/Schema";
-import { SchemaHeaderField } from "../../../../new_fields/SchemaHeaderField";
-import { ComputedField } from "../../../../new_fields/ScriptField";
-import { Cast, StrCast } from "../../../../new_fields/Types";
+import { Doc, DocListCast, Field } from "../../../../fields/Doc";
+import { List } from "../../../../fields/List";
+import { listSpec } from "../../../../fields/Schema";
+import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField";
+import { ComputedField } from "../../../../fields/ScriptField";
+import { Cast, StrCast } from "../../../../fields/Types";
 import { DocServer } from "../../../DocServer";
 import { CollectionViewType } from "../../collections/CollectionView";
 import { FormattedTextBox } from "./FormattedTextBox";
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 206c3db8c..5e33e7e70 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -12,17 +12,17 @@ import { Fragment, Mark, Node, Slice } from "prosemirror-model";
 import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from "prosemirror-state";
 import { ReplaceStep } from 'prosemirror-transform';
 import { EditorView } from "prosemirror-view";
-import { DateField } from '../../../../new_fields/DateField';
-import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym } from "../../../../new_fields/Doc";
-import { documentSchema } from '../../../../new_fields/documentSchemas';
-import { Id } from '../../../../new_fields/FieldSymbols';
-import { InkTool } from '../../../../new_fields/InkField';
-import { PrefetchProxy } from '../../../../new_fields/Proxy';
-import { RichTextField } from "../../../../new_fields/RichTextField";
-import { RichTextUtils } from '../../../../new_fields/RichTextUtils';
-import { createSchema, makeInterface } from "../../../../new_fields/Schema";
-import { Cast, DateCast, NumCast, StrCast } from "../../../../new_fields/Types";
-import { TraceMobx } from '../../../../new_fields/util';
+import { DateField } from '../../../../fields/DateField';
+import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym } from "../../../../fields/Doc";
+import { documentSchema } from '../../../../fields/documentSchemas';
+import { Id } from '../../../../fields/FieldSymbols';
+import { InkTool } from '../../../../fields/InkField';
+import { PrefetchProxy } from '../../../../fields/Proxy';
+import { RichTextField } from "../../../../fields/RichTextField";
+import { RichTextUtils } from '../../../../fields/RichTextUtils';
+import { createSchema, makeInterface } from "../../../../fields/Schema";
+import { Cast, DateCast, NumCast, StrCast } from "../../../../fields/Types";
+import { TraceMobx } from '../../../../fields/util';
 import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, numberRange, returnOne, returnZero, Utils, setupMoveUpEvents } from '../../../../Utils';
 import { GoogleApiClientUtils, Pulls, Pushes } from '../../../apis/google_docs/GoogleApiClientUtils';
 import { DocServer } from "../../../DocServer";
@@ -58,7 +58,7 @@ import { FieldView, FieldViewProps } from "../FieldView";
 import "./FormattedTextBox.scss";
 import { FormattedTextBoxComment, formattedTextBoxCommentPlugin } from './FormattedTextBoxComment';
 import React = require("react");
-import { ScriptField } from '../../../../new_fields/ScriptField';
+import { ScriptField } from '../../../../fields/ScriptField';
 import GoogleAuthenticationManager from '../../../apis/GoogleAuthenticationManager';
 
 library.add(faEdit);
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 07aecf148..d47ae63af 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -2,8 +2,8 @@ import { Mark, ResolvedPos } from "prosemirror-model";
 import { EditorState, Plugin } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import * as ReactDOM from 'react-dom';
-import { Doc, DocCastAsync } from "../../../../new_fields/Doc";
-import { Cast, FieldValue, NumCast } from "../../../../new_fields/Types";
+import { Doc, DocCastAsync } from "../../../../fields/Doc";
+import { Cast, FieldValue, NumCast } from "../../../../fields/Types";
 import { emptyFunction, returnEmptyString, returnFalse, Utils, emptyPath, returnZero, returnOne } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
 import { DocumentManager } from "../../../util/DocumentManager";
diff --git a/src/client/views/nodes/formattedText/ImageResizeView.tsx b/src/client/views/nodes/formattedText/ImageResizeView.tsx
index 8f98da0fd..401ecd7e6 100644
--- a/src/client/views/nodes/formattedText/ImageResizeView.tsx
+++ b/src/client/views/nodes/formattedText/ImageResizeView.tsx
@@ -1,5 +1,5 @@
 import { NodeSelection } from "prosemirror-state";
-import { Doc } from "../../../../new_fields/Doc";
+import { Doc } from "../../../../fields/Doc";
 import { DocServer } from "../../../DocServer";
 import { DocumentManager } from "../../../util/DocumentManager";
 import React = require("react");
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
index a0b02880e..2f7d23021 100644
--- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
+++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
@@ -7,10 +7,10 @@ import { splitListItem, wrapInList, } from "prosemirror-schema-list";
 import { EditorState, Transaction, TextSelection } from "prosemirror-state";
 import { SelectionManager } from "../../../util/SelectionManager";
 import { Docs } from "../../../documents/Documents";
-import { NumCast, BoolCast, Cast, StrCast } from "../../../../new_fields/Types";
-import { Doc } from "../../../../new_fields/Doc";
+import { NumCast, BoolCast, Cast, StrCast } from "../../../../fields/Types";
+import { Doc } from "../../../../fields/Doc";
 import { FormattedTextBox } from "./FormattedTextBox";
-import { Id } from "../../../../new_fields/FieldSymbols";
+import { Id } from "../../../../fields/FieldSymbols";
 
 const mac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false;
 
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 170a39801..fd1b26208 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -11,14 +11,14 @@ import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
 import { faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent, faEyeDropper, faCaretDown, faPalette, faHighlighter, faLink, faPaintRoller, faSleigh } from "@fortawesome/free-solid-svg-icons";
 import { updateBullets } from "./ProsemirrorExampleTransfer";
 import { FieldViewProps } from "../FieldView";
-import { Cast, StrCast } from "../../../../new_fields/Types";
+import { Cast, StrCast } from "../../../../fields/Types";
 import { FormattedTextBoxProps } from "./FormattedTextBox";
 import { unimplementedFunction, Utils } from "../../../../Utils";
 import { wrapInList } from "prosemirror-schema-list";
-import { PastelSchemaPalette, DarkPastelSchemaPalette } from '../../../../new_fields/SchemaHeaderField';
+import { PastelSchemaPalette, DarkPastelSchemaPalette } from '../../../../fields/SchemaHeaderField';
 import "./RichTextMenu.scss";
 import { DocServer } from "../../../DocServer";
-import { Doc } from "../../../../new_fields/Doc";
+import { Doc } from "../../../../fields/Doc";
 import { SelectionManager } from "../../../util/SelectionManager";
 import { LinkManager } from "../../../util/LinkManager";
 const { toggleMark, setBlockType } = require("prosemirror-commands");
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index 0ba591fec..fbd6c87bb 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -1,9 +1,9 @@
 import { ellipsis, emDash, InputRule, smartQuotes, textblockTypeInputRule } from "prosemirror-inputrules";
 import { NodeSelection, TextSelection } from "prosemirror-state";
-import { DataSym, Doc } from "../../../../new_fields/Doc";
-import { Id } from "../../../../new_fields/FieldSymbols";
-import { ComputedField } from "../../../../new_fields/ScriptField";
-import { Cast, NumCast } from "../../../../new_fields/Types";
+import { DataSym, Doc } from "../../../../fields/Doc";
+import { Id } from "../../../../fields/FieldSymbols";
+import { ComputedField } from "../../../../fields/ScriptField";
+import { Cast, NumCast } from "../../../../fields/Types";
 import { returnFalse, Utils } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
 import { Docs, DocUtils } from "../../../documents/Documents";
@@ -11,7 +11,7 @@ import { FormattedTextBox } from "./FormattedTextBox";
 import { wrappingInputRule } from "./prosemirrorPatches";
 import RichTextMenu from "./RichTextMenu";
 import { schema } from "./schema_rts";
-import { List } from "../../../../new_fields/List";
+import { List } from "../../../../fields/List";
 
 export class RichTextRules {
     public Document: Doc;
diff --git a/src/client/views/nodes/formattedText/RichTextSchema.tsx b/src/client/views/nodes/formattedText/RichTextSchema.tsx
index 7edd191cf..91280dea4 100644
--- a/src/client/views/nodes/formattedText/RichTextSchema.tsx
+++ b/src/client/views/nodes/formattedText/RichTextSchema.tsx
@@ -8,14 +8,14 @@ import { EditorState, NodeSelection, Plugin, TextSelection } from "prosemirror-s
 import { StepMap } from "prosemirror-transform";
 import { EditorView } from "prosemirror-view";
 import * as ReactDOM from 'react-dom';
-import { Doc, DocListCast, Field, HeightSym, WidthSym } from "../../../../new_fields/Doc";
-import { Id } from "../../../../new_fields/FieldSymbols";
-import { List } from "../../../../new_fields/List";
-import { ObjectField } from "../../../../new_fields/ObjectField";
-import { listSpec } from "../../../../new_fields/Schema";
-import { SchemaHeaderField } from "../../../../new_fields/SchemaHeaderField";
-import { ComputedField } from "../../../../new_fields/ScriptField";
-import { BoolCast, Cast, NumCast, StrCast, FieldValue } from "../../../../new_fields/Types";
+import { Doc, DocListCast, Field, HeightSym, WidthSym } from "../../../../fields/Doc";
+import { Id } from "../../../../fields/FieldSymbols";
+import { List } from "../../../../fields/List";
+import { ObjectField } from "../../../../fields/ObjectField";
+import { listSpec } from "../../../../fields/Schema";
+import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField";
+import { ComputedField } from "../../../../fields/ScriptField";
+import { BoolCast, Cast, NumCast, StrCast, FieldValue } from "../../../../fields/Types";
 import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils, returnZero } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
 import { Docs } from "../../../documents/Documents";
diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts
index 46bf481fb..ebaa23e99 100644
--- a/src/client/views/nodes/formattedText/marks_rts.ts
+++ b/src/client/views/nodes/formattedText/marks_rts.ts
@@ -1,6 +1,6 @@
 import React = require("react");
 import { DOMOutputSpecArray, Fragment, MarkSpec, Node, NodeSpec, Schema, Slice } from "prosemirror-model";
-import { Doc } from "../../../../new_fields/Doc";
+import { Doc } from "../../../../fields/Doc";
 
 
 const emDOM: DOMOutputSpecArray = ["em", 0];
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 672d3adb8..cb6a15f36 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -1,10 +1,10 @@
 import React = require("react");
 import { action, IReactionDisposer, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast, HeightSym, WidthSym } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { List } from "../../../new_fields/List";
-import { Cast, FieldValue, NumCast, StrCast } from "../../../new_fields/Types";
+import { Doc, DocListCast, HeightSym, WidthSym } from "../../../fields/Doc";
+import { Id } from "../../../fields/FieldSymbols";
+import { List } from "../../../fields/List";
+import { Cast, FieldValue, NumCast, StrCast } from "../../../fields/Types";
 import { DocumentManager } from "../../util/DocumentManager";
 import PDFMenu from "./PDFMenu";
 import "./Annotation.scss";
diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx
index 2a6eff7ff..ff328068b 100644
--- a/src/client/views/pdf/PDFMenu.tsx
+++ b/src/client/views/pdf/PDFMenu.tsx
@@ -5,7 +5,7 @@ import { observer } from "mobx-react";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { unimplementedFunction, returnFalse } from "../../../Utils";
 import AntimodeMenu from "../AntimodeMenu";
-import { Doc, Opt } from "../../../new_fields/Doc";
+import { Doc, Opt } from "../../../fields/Doc";
 
 @observer
 export default class PDFMenu extends AntimodeMenu {
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index acaa4363e..c50969493 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -4,16 +4,16 @@ import * as Pdfjs from "pdfjs-dist";
 import "pdfjs-dist/web/pdf_viewer.css";
 import * as rp from "request-promise";
 import { Dictionary } from "typescript-collections";
-import { Doc, DocListCast, FieldResult, HeightSym, Opt, WidthSym } from "../../../new_fields/Doc";
-import { documentSchema } from "../../../new_fields/documentSchemas";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { InkTool } from "../../../new_fields/InkField";
-import { List } from "../../../new_fields/List";
-import { createSchema, makeInterface } from "../../../new_fields/Schema";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { Cast, NumCast } from "../../../new_fields/Types";
-import { PdfField } from "../../../new_fields/URLField";
-import { TraceMobx } from "../../../new_fields/util";
+import { Doc, DocListCast, FieldResult, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { Id } from "../../../fields/FieldSymbols";
+import { InkTool } from "../../../fields/InkField";
+import { List } from "../../../fields/List";
+import { createSchema, makeInterface } from "../../../fields/Schema";
+import { ScriptField } from "../../../fields/ScriptField";
+import { Cast, NumCast } from "../../../fields/Types";
+import { PdfField } from "../../../fields/URLField";
+import { TraceMobx } from "../../../fields/util";
 import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, emptyPath, intersectRect, returnZero, smoothScroll, Utils } from "../../../Utils";
 import { Docs, DocUtils } from "../../documents/Documents";
 import { DocumentType } from "../../documents/DocumentTypes";
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index e13a5f2f7..280ba9093 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -1,11 +1,11 @@
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, IReactionDisposer, reaction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DataSym, DocListCast } from "../../../new_fields/Doc";
-import { documentSchema } from '../../../new_fields/documentSchemas';
-import { Id } from "../../../new_fields/FieldSymbols";
-import { createSchema, makeInterface } from '../../../new_fields/Schema';
-import { Cast, NumCast, BoolCast, ScriptCast } from "../../../new_fields/Types";
+import { Doc, DataSym, DocListCast } from "../../../fields/Doc";
+import { documentSchema } from '../../../fields/documentSchemas';
+import { Id } from "../../../fields/FieldSymbols";
+import { createSchema, makeInterface } from '../../../fields/Schema';
+import { Cast, NumCast, BoolCast, ScriptCast } from "../../../fields/Types";
 import { emptyFunction, emptyPath, returnFalse, returnTrue, returnOne, returnZero } from "../../../Utils";
 import { Transform } from "../../util/Transform";
 import { CollectionViewType } from '../collections/CollectionView';
diff --git a/src/client/views/search/FilterBox.tsx b/src/client/views/search/FilterBox.tsx
index 662b37d77..4b53963a5 100644
--- a/src/client/views/search/FilterBox.tsx
+++ b/src/client/views/search/FilterBox.tsx
@@ -4,10 +4,10 @@ import { observable, action } from 'mobx';
 import "./SearchBox.scss";
 import { faTimes, faCheckCircle, faObjectGroup } from '@fortawesome/free-solid-svg-icons';
 import { library } from '@fortawesome/fontawesome-svg-core';
-import { Doc } from '../../../new_fields/Doc';
-import { Id } from '../../../new_fields/FieldSymbols';
+import { Doc } from '../../../fields/Doc';
+import { Id } from '../../../fields/FieldSymbols';
 import { DocumentType } from "../../documents/DocumentTypes";
-import { Cast, StrCast } from '../../../new_fields/Types';
+import { Cast, StrCast } from '../../../fields/Types';
 import * as _ from "lodash";
 import { IconBar } from './IconBar';
 import { FieldFilters } from './FieldFilters';
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index e41b725b1..eea7b528b 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -5,9 +5,9 @@ import { action, computed, observable, runInAction, IReactionDisposer, reaction
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import * as rp from 'request-promise';
-import { Doc } from '../../../new_fields/Doc';
-import { Id } from '../../../new_fields/FieldSymbols';
-import { Cast, NumCast, StrCast } from '../../../new_fields/Types';
+import { Doc } from '../../../fields/Doc';
+import { Id } from '../../../fields/FieldSymbols';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
 import { Utils } from '../../../Utils';
 import { Docs } from '../../documents/Documents';
 import { SetupDrag } from '../../util/DragManager';
@@ -19,7 +19,7 @@ import { FieldView } from '../nodes/FieldView';
 import { DocumentType } from "../../documents/DocumentTypes";
 import { DocumentView } from '../nodes/DocumentView';
 import { SelectionManager } from '../../util/SelectionManager';
-import { listSpec } from '../../../new_fields/Schema';
+import { listSpec } from '../../../fields/Schema';
 
 library.add(faTimes);
 
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index 96f43e931..24d6e9d6f 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -4,9 +4,9 @@ import { faCaretUp, faChartBar, faFile, faFilePdf, faFilm, faFingerprint, faGlob
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Doc } from "../../../fields/Doc";
+import { Id } from "../../../fields/FieldSymbols";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
 import { emptyFunction, emptyPath, returnFalse, Utils, returnTrue, returnOne, returnZero } from "../../../Utils";
 import { DocumentType } from "../../documents/DocumentTypes";
 import { DocumentManager } from "../../util/DocumentManager";
diff --git a/src/debug/Repl.tsx b/src/debug/Repl.tsx
index fd6b47ff0..d541c8009 100644
--- a/src/debug/Repl.tsx
+++ b/src/debug/Repl.tsx
@@ -3,9 +3,9 @@ import * as ReactDOM from 'react-dom';
 import { observer } from 'mobx-react';
 import { observable, computed } from 'mobx';
 import { CompileScript } from '../client/util/Scripting';
-import { makeInterface } from '../new_fields/Schema';
-import { ObjectField } from '../new_fields/ObjectField';
-import { RefField } from '../new_fields/RefField';
+import { makeInterface } from '../fields/Schema';
+import { ObjectField } from '../fields/ObjectField';
+import { RefField } from '../fields/RefField';
 import { DocServer } from '../client/DocServer';
 
 @observer
diff --git a/src/debug/Test.tsx b/src/debug/Test.tsx
index 3baedce4b..17d3db8fd 100644
--- a/src/debug/Test.tsx
+++ b/src/debug/Test.tsx
@@ -1,7 +1,7 @@
 import * as React from 'react';
 import * as ReactDOM from 'react-dom';
 import { DocServer } from '../client/DocServer';
-import { Doc } from '../new_fields/Doc';
+import { Doc } from '../fields/Doc';
 import * as Pdfjs from "pdfjs-dist";
 import "pdfjs-dist/web/pdf_viewer.css";
 import { Utils } from '../Utils';
diff --git a/src/debug/Viewer.tsx b/src/debug/Viewer.tsx
index a26d2e06a..6ce39d533 100644
--- a/src/debug/Viewer.tsx
+++ b/src/debug/Viewer.tsx
@@ -3,17 +3,17 @@ import "normalize.css";
 import * as React from 'react';
 import * as ReactDOM from 'react-dom';
 import { observer } from 'mobx-react';
-import { Doc, Field, FieldResult, Opt } from '../new_fields/Doc';
+import { Doc, Field, FieldResult, Opt } from '../fields/Doc';
 import { DocServer } from '../client/DocServer';
-import { Id } from '../new_fields/FieldSymbols';
-import { List } from '../new_fields/List';
-import { URLField } from '../new_fields/URLField';
+import { Id } from '../fields/FieldSymbols';
+import { List } from '../fields/List';
+import { URLField } from '../fields/URLField';
 import { EditableView } from '../client/views/EditableView';
 import { CompileScript } from '../client/util/Scripting';
-import { RichTextField } from '../new_fields/RichTextField';
-import { DateField } from '../new_fields/DateField';
-import { ScriptField } from '../new_fields/ScriptField';
-import CursorField from '../new_fields/CursorField';
+import { RichTextField } from '../fields/RichTextField';
+import { DateField } from '../fields/DateField';
+import { ScriptField } from '../fields/ScriptField';
+import CursorField from '../fields/CursorField';
 
 DateField;
 URLField;
diff --git a/src/fields/CursorField.ts b/src/fields/CursorField.ts
new file mode 100644
index 000000000..28467377b
--- /dev/null
+++ b/src/fields/CursorField.ts
@@ -0,0 +1,66 @@
+import { ObjectField } from "./ObjectField";
+import { observable } from "mobx";
+import { Deserializable } from "../client/util/SerializationHelper";
+import { serializable, createSimpleSchema, object, date } from "serializr";
+import { OnUpdate, ToScriptString, ToString, Copy } from "./FieldSymbols";
+
+export type CursorPosition = {
+    x: number,
+    y: number
+};
+
+export type CursorMetadata = {
+    id: string,
+    identifier: string,
+    timestamp: number
+};
+
+export type CursorData = {
+    metadata: CursorMetadata,
+    position: CursorPosition
+};
+
+const PositionSchema = createSimpleSchema({
+    x: true,
+    y: true
+});
+
+const MetadataSchema = createSimpleSchema({
+    id: true,
+    identifier: true,
+    timestamp: true
+});
+
+const CursorSchema = createSimpleSchema({
+    metadata: object(MetadataSchema),
+    position: object(PositionSchema)
+});
+
+@Deserializable("cursor")
+export default class CursorField extends ObjectField {
+
+    @serializable(object(CursorSchema))
+    readonly data: CursorData;
+
+    constructor(data: CursorData) {
+        super();
+        this.data = data;
+    }
+
+    setPosition(position: CursorPosition) {
+        this.data.position = position;
+        this.data.metadata.timestamp = Date.now();
+        this[OnUpdate]();
+    }
+
+    [Copy]() {
+        return new CursorField(this.data);
+    }
+
+    [ToScriptString]() {
+        return "invalid";
+    }
+    [ToString]() {
+        return "invalid";
+    }
+}
\ No newline at end of file
diff --git a/src/fields/DateField.ts b/src/fields/DateField.ts
new file mode 100644
index 000000000..a925148c2
--- /dev/null
+++ b/src/fields/DateField.ts
@@ -0,0 +1,36 @@
+import { Deserializable } from "../client/util/SerializationHelper";
+import { serializable, date } from "serializr";
+import { ObjectField } from "./ObjectField";
+import { Copy, ToScriptString, ToString } from "./FieldSymbols";
+import { scriptingGlobal, Scripting } from "../client/util/Scripting";
+
+@scriptingGlobal
+@Deserializable("date")
+export class DateField extends ObjectField {
+    @serializable(date())
+    readonly date: Date;
+
+    constructor(date: Date = new Date()) {
+        super();
+        this.date = date;
+    }
+
+    [Copy]() {
+        return new DateField(this.date);
+    }
+
+    toString() {
+        return `${this.date.toISOString()}`;
+    }
+
+    [ToScriptString]() {
+        return `new DateField(new Date(${this.date.toISOString()}))`;
+    }
+    [ToString]() {
+        return this.date.toISOString();
+    }
+}
+
+Scripting.addGlobal(function d(...dateArgs: any[]) {
+    return new DateField(new (Date as any)(...dateArgs));
+});
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
new file mode 100644
index 000000000..a1e1e11b1
--- /dev/null
+++ b/src/fields/Doc.ts
@@ -0,0 +1,1109 @@
+import { action, computed, observable, ObservableMap, runInAction } from "mobx";
+import { computedFn } from "mobx-utils";
+import { alias, map, serializable } from "serializr";
+import { DocServer } from "../client/DocServer";
+import { DocumentType } from "../client/documents/DocumentTypes";
+import { Scripting, scriptingGlobal } from "../client/util/Scripting";
+import { afterDocDeserialize, autoObject, Deserializable, SerializationHelper } from "../client/util/SerializationHelper";
+import { UndoManager } from "../client/util/UndoManager";
+import { intersectRect, Utils } from "../Utils";
+import { HandleUpdate, Id, OnUpdate, Parent, Self, SelfProxy, ToScriptString, ToString, Update, Copy } from "./FieldSymbols";
+import { List } from "./List";
+import { ObjectField } from "./ObjectField";
+import { PrefetchProxy, ProxyField } from "./Proxy";
+import { FieldId, RefField } from "./RefField";
+import { RichTextField } from "./RichTextField";
+import { listSpec } from "./Schema";
+import { ComputedField, ScriptField } from "./ScriptField";
+import { Cast, FieldValue, NumCast, StrCast, ToConstructor, ScriptCast } from "./Types";
+import { deleteProperty, getField, getter, makeEditable, makeReadOnly, setter, updateFunction } from "./util";
+import { Docs, DocumentOptions } from "../client/documents/Documents";
+import { PdfField, VideoField, AudioField, ImageField } from "./URLField";
+import { LinkManager } from "../client/util/LinkManager";
+
+export namespace Field {
+    export function toKeyValueString(doc: Doc, key: string): string {
+        const onDelegate = Object.keys(doc).includes(key);
+
+        const field = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
+        if (Field.IsField(field)) {
+            return (onDelegate ? "=" : "") + (field instanceof ComputedField ? `:=${field.script.originalScript}` : Field.toScriptString(field));
+        }
+        return "";
+    }
+    export function toScriptString(field: Field): string {
+        if (typeof field === "string") {
+            return `"${field}"`;
+        } else if (typeof field === "number" || typeof field === "boolean") {
+            return String(field);
+        } else {
+            return field[ToScriptString]();
+        }
+    }
+    export function toString(field: Field): string {
+        if (typeof field === "string") {
+            return field;
+        } else if (typeof field === "number" || typeof field === "boolean") {
+            return String(field);
+        } else if (field instanceof ObjectField) {
+            return field[ToString]();
+        } else if (field instanceof RefField) {
+            return field[ToString]();
+        }
+        return "";
+    }
+    export function IsField(field: any): field is Field;
+    export function IsField(field: any, includeUndefined: true): field is Field | undefined;
+    export function IsField(field: any, includeUndefined: boolean = false): field is Field | undefined {
+        return (typeof field === "string")
+            || (typeof field === "number")
+            || (typeof field === "boolean")
+            || (field instanceof ObjectField)
+            || (field instanceof RefField)
+            || (includeUndefined && field === undefined);
+    }
+}
+export type Field = number | string | boolean | ObjectField | RefField;
+export type Opt<T> = T | undefined;
+export type FieldWaiting<T extends RefField = RefField> = T extends undefined ? never : Promise<T | undefined>;
+export type FieldResult<T extends Field = Field> = Opt<T> | FieldWaiting<Extract<T, RefField>>;
+
+/**
+ * Cast any field to either a List of Docs or undefined if the given field isn't a List of Docs.  
+ * If a default value is given, that will be returned instead of undefined.  
+ * If a default value is given, the returned value should not be modified as it might be a temporary value.  
+ * If no default value is given, and the returned value is not undefined, it can be safely modified.  
+ */
+export function DocListCastAsync(field: FieldResult): Promise<Doc[] | undefined>;
+export function DocListCastAsync(field: FieldResult, defaultValue: Doc[]): Promise<Doc[]>;
+export function DocListCastAsync(field: FieldResult, defaultValue?: Doc[]) {
+    const list = Cast(field, listSpec(Doc));
+    return list ? Promise.all(list).then(() => list) : Promise.resolve(defaultValue);
+}
+
+export async function DocCastAsync(field: FieldResult): Promise<Opt<Doc>> {
+    return Cast(field, Doc);
+}
+
+export function DocListCast(field: FieldResult): Doc[] {
+    return Cast(field, listSpec(Doc), []).filter(d => d instanceof Doc) as Doc[];
+}
+
+export const WidthSym = Symbol("Width");
+export const HeightSym = Symbol("Height");
+export const DataSym = Symbol("Data");
+export const LayoutSym = Symbol("Layout");
+export const UpdatingFromServer = Symbol("UpdatingFromServer");
+const CachedUpdates = Symbol("Cached updates");
+
+
+function fetchProto(doc: Doc) {
+    const proto = doc.proto;
+    if (proto instanceof Promise) {
+        return proto;
+    }
+}
+
+@scriptingGlobal
+@Deserializable("Doc", fetchProto).withFields(["id"])
+export class Doc extends RefField {
+    constructor(id?: FieldId, forceSave?: boolean) {
+        super(id);
+        const doc = new Proxy<this>(this, {
+            set: setter,
+            get: getter,
+            // getPrototypeOf: (target) => Cast(target[SelfProxy].proto, Doc) || null, // TODO this might be able to replace the proto logic in getter
+            has: (target, key) => key in target.__fields,
+            ownKeys: target => {
+                const obj = {} as any;
+                Object.assign(obj, target.___fields);
+                runInAction(() => obj.__LAYOUT__ = target.__LAYOUT__);
+                return Object.keys(obj);
+            },
+            getOwnPropertyDescriptor: (target, prop) => {
+                if (prop.toString() === "__LAYOUT__") {
+                    return Reflect.getOwnPropertyDescriptor(target, prop);
+                }
+                if (prop in target.__fields) {
+                    return {
+                        configurable: true,//TODO Should configurable be true?
+                        enumerable: true,
+                        value: target.__fields[prop]
+                    };
+                }
+                return Reflect.getOwnPropertyDescriptor(target, prop);
+            },
+            deleteProperty: deleteProperty,
+            defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
+        });
+        this[SelfProxy] = doc;
+        if (!id || forceSave) {
+            DocServer.CreateField(doc);
+        }
+        return doc;
+    }
+
+    proto: Opt<Doc>;
+    [key: string]: FieldResult;
+
+    @serializable(alias("fields", map(autoObject(), { afterDeserialize: afterDocDeserialize })))
+    private get __fields() { return this.___fields; }
+    private set __fields(value) {
+        this.___fields = value;
+        for (const key in value) {
+            const field = value[key];
+            if (!(field instanceof ObjectField)) continue;
+            field[Parent] = this[Self];
+            field[OnUpdate] = updateFunction(this[Self], key, field, this[SelfProxy]);
+        }
+    }
+
+    @observable
+    //{ [key: string]: Field | FieldWaiting | undefined }
+    private ___fields: any = {};
+
+    private [UpdatingFromServer]: boolean = false;
+
+    private [Update] = (diff: any) => {
+        !this[UpdatingFromServer] && DocServer.UpdateField(this[Id], diff);
+    }
+
+    private [Self] = this;
+    private [SelfProxy]: any;
+    public [WidthSym] = () => NumCast(this[SelfProxy]._width);
+    public [HeightSym] = () => NumCast(this[SelfProxy]._height);
+    public get [LayoutSym]() { return this[SelfProxy].__LAYOUT__; }
+    public get [DataSym]() {
+        const self = this[SelfProxy];
+        return self.resolvedDataDoc && !self.isTemplateForField ? self :
+            Doc.GetProto(Cast(Doc.Layout(self).resolvedDataDoc, Doc, null) || self);
+    }
+    @computed get __LAYOUT__() {
+        const templateLayoutDoc = Cast(Doc.LayoutField(this[SelfProxy]), Doc, null);
+        if (templateLayoutDoc) {
+            let renderFieldKey: any;
+            const layoutField = templateLayoutDoc[StrCast(templateLayoutDoc.layoutKey, "layout")];
+            if (typeof layoutField === "string") {
+                renderFieldKey = layoutField.split("fieldKey={'")[1].split("'")[0];//layoutField.split("'")[1];
+            } else {
+                return Cast(layoutField, Doc, null);
+            }
+            return Cast(this[SelfProxy][renderFieldKey + "-layout[" + templateLayoutDoc[Id] + "]"], Doc, null) || templateLayoutDoc;
+        }
+        return undefined;
+    }
+
+    [ToScriptString]() { return `DOC-"${this[Self][Id]}"-`; }
+    [ToString]() { return `Doc(${this.title})`; }
+
+    private [CachedUpdates]: { [key: string]: () => void | Promise<any> } = {};
+    public static CurrentUserEmail: string = "";
+    public async [HandleUpdate](diff: any) {
+        const set = diff.$set;
+        const sameAuthor = this.author === Doc.CurrentUserEmail;
+        if (set) {
+            for (const key in set) {
+                if (!key.startsWith("fields.")) {
+                    continue;
+                }
+                const fKey = key.substring(7);
+                const fn = async () => {
+                    const value = await SerializationHelper.Deserialize(set[key]);
+                    this[UpdatingFromServer] = true;
+                    this[fKey] = value;
+                    this[UpdatingFromServer] = false;
+                };
+                if (sameAuthor || DocServer.getFieldWriteMode(fKey) !== DocServer.WriteMode.Playground) {
+                    delete this[CachedUpdates][fKey];
+                    await fn();
+                } else {
+                    this[CachedUpdates][fKey] = fn;
+                }
+            }
+        }
+        const unset = diff.$unset;
+        if (unset) {
+            for (const key in unset) {
+                if (!key.startsWith("fields.")) {
+                    continue;
+                }
+                const fKey = key.substring(7);
+                const fn = () => {
+                    this[UpdatingFromServer] = true;
+                    delete this[fKey];
+                    this[UpdatingFromServer] = false;
+                };
+                if (sameAuthor || DocServer.getFieldWriteMode(fKey) !== DocServer.WriteMode.Playground) {
+                    delete this[CachedUpdates][fKey];
+                    await fn();
+                } else {
+                    this[CachedUpdates][fKey] = fn;
+                }
+            }
+        }
+    }
+}
+
+export namespace Doc {
+    // export function GetAsync(doc: Doc, key: string, ignoreProto: boolean = false): Promise<Field | undefined> {
+    //     const self = doc[Self];
+    //     return new Promise(res => getField(self, key, ignoreProto, res));
+    // }
+    // export function GetTAsync<T extends Field>(doc: Doc, key: string, ctor: ToConstructor<T>, ignoreProto: boolean = false): Promise<T | undefined> {
+    //     return new Promise(async res => {
+    //         const field = await GetAsync(doc, key, ignoreProto);
+    //         return Cast(field, ctor);
+    //     });
+    // }
+
+    export function RunCachedUpdate(doc: Doc, field: string) {
+        const update = doc[CachedUpdates][field];
+        if (update) {
+            update();
+            delete doc[CachedUpdates][field];
+        }
+    }
+    export function AddCachedUpdate(doc: Doc, field: string, oldValue: any) {
+        const val = oldValue;
+        doc[CachedUpdates][field] = () => {
+            doc[UpdatingFromServer] = true;
+            doc[field] = val;
+            doc[UpdatingFromServer] = false;
+        };
+    }
+    export function MakeReadOnly(): { end(): void } {
+        makeReadOnly();
+        return {
+            end() {
+                makeEditable();
+            }
+        };
+    }
+
+    export function Get(doc: Doc, key: string, ignoreProto: boolean = false): FieldResult {
+        try {
+            return getField(doc[Self], key, ignoreProto);
+        } catch  {
+            return doc;
+        }
+    }
+    export function GetT<T extends Field>(doc: Doc, key: string, ctor: ToConstructor<T>, ignoreProto: boolean = false): FieldResult<T> {
+        return Cast(Get(doc, key, ignoreProto), ctor) as FieldResult<T>;
+    }
+    export function IsPrototype(doc: Doc) {
+        return GetT(doc, "isPrototype", "boolean", true);
+    }
+    export function IsBaseProto(doc: Doc) {
+        return GetT(doc, "baseProto", "boolean", true);
+    }
+    export async function SetInPlace(doc: Doc, key: string, value: Field | undefined, defaultProto: boolean) {
+        const hasProto = doc.proto instanceof Doc;
+        const onDeleg = Object.getOwnPropertyNames(doc).indexOf(key) !== -1;
+        const onProto = hasProto && Object.getOwnPropertyNames(doc.proto).indexOf(key) !== -1;
+        if (onDeleg || !hasProto || (!onProto && !defaultProto)) {
+            doc[key] = value;
+        } else doc.proto![key] = value;
+    }
+    export async function SetOnPrototype(doc: Doc, key: string, value: Field) {
+        const proto = Object.getOwnPropertyNames(doc).indexOf("isPrototype") === -1 ? doc.proto : doc;
+
+        if (proto) {
+            proto[key] = value;
+        }
+    }
+    export function GetAllPrototypes(doc: Doc): Doc[] {
+        const protos: Doc[] = [];
+        let d: Opt<Doc> = doc;
+        while (d) {
+            protos.push(d);
+            d = FieldValue(d.proto);
+        }
+        return protos;
+    }
+
+    /**
+     * This function is intended to model Object.assign({}, {}) [https://mzl.la/1Mo3l21], which copies
+     * the values of the properties of a source object into the target.
+     * 
+     * This is just a specific, Dash-authored version that serves the same role for our
+     * Doc class.
+     * 
+     * @param doc the target document into which you'd like to insert the new fields 
+     * @param fields the fields to project onto the target. Its type signature defines a mapping from some string key
+     * to a potentially undefined field, where each entry in this mapping is optional. 
+     */
+    export function assign<K extends string>(doc: Doc, fields: Partial<Record<K, Opt<Field>>>, skipUndefineds: boolean = false) {
+        for (const key in fields) {
+            if (fields.hasOwnProperty(key)) {
+                const value = fields[key];
+                if (!skipUndefineds || value !== undefined) { // Do we want to filter out undefineds?
+                    doc[key] = value;
+                }
+            }
+        }
+        return doc;
+    }
+
+    // compare whether documents or their protos match
+    export function AreProtosEqual(doc?: Doc, other?: Doc) {
+        if (!doc || !other) return false;
+        const r = (doc === other);
+        const r2 = (Doc.GetProto(doc) === other);
+        const r3 = (Doc.GetProto(other) === doc);
+        const r4 = (Doc.GetProto(doc) === Doc.GetProto(other) && Doc.GetProto(other) !== undefined);
+        return r || r2 || r3 || r4;
+    }
+
+    // Gets the data document for the document.  Note: this is mis-named -- it does not specifically
+    // return the doc's proto, but rather recursively searches through the proto inheritance chain 
+    // and returns the document who's proto is undefined or whose proto is marked as a base prototype ('isPrototype').
+    export function GetProto(doc: Doc): Doc {
+        if (doc instanceof Promise) {
+            console.log("GetProto: error: got Promise insead of Doc");
+        }
+        const proto = doc && (Doc.GetT(doc, "isPrototype", "boolean", true) ? doc : (doc.proto || doc));
+        return proto === doc ? proto : Doc.GetProto(proto);
+    }
+    export function GetDataDoc(doc: Doc): Doc {
+        const proto = Doc.GetProto(doc);
+        return proto === doc ? proto : Doc.GetDataDoc(proto);
+    }
+
+    export function allKeys(doc: Doc): string[] {
+        const results: Set<string> = new Set;
+
+        let proto: Doc | undefined = doc;
+        while (proto) {
+            Object.keys(proto).forEach(key => results.add(key));
+            proto = proto.proto;
+        }
+
+        return Array.from(results);
+    }
+
+    export function IndexOf(toFind: Doc, list: Doc[], allowProtos: boolean = true) {
+        let index = list.reduce((p, v, i) => (v instanceof Doc && v === toFind) ? i : p, -1);
+        index = allowProtos && index !== -1 ? index : list.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, toFind)) ? i : p, -1);
+        return index; // list.findIndex(doc => doc === toFind || Doc.AreProtosEqual(doc, toFind));
+    }
+    export function RemoveDocFromList(listDoc: Doc, fieldKey: string | undefined, doc: Doc) {
+        const key = fieldKey ? fieldKey : Doc.LayoutFieldKey(listDoc);
+        if (listDoc[key] === undefined) {
+            Doc.GetProto(listDoc)[key] = new List<Doc>();
+        }
+        const list = Cast(listDoc[key], listSpec(Doc));
+        if (list) {
+            const ind = list.indexOf(doc);
+            if (ind !== -1) {
+                list.splice(ind, 1);
+                return true;
+            }
+        }
+        return false;
+    }
+    export function AddDocToList(listDoc: Doc, fieldKey: string | undefined, doc: Doc, relativeTo?: Doc, before?: boolean, first?: boolean, allowDuplicates?: boolean, reversed?: boolean) {
+        const key = fieldKey ? fieldKey : Doc.LayoutFieldKey(listDoc);
+        if (listDoc[key] === undefined) {
+            Doc.GetProto(listDoc)[key] = new List<Doc>();
+        }
+        const list = Cast(listDoc[key], listSpec(Doc));
+        if (list) {
+            if (allowDuplicates !== true) {
+                const pind = list.reduce((l, d, i) => d instanceof Doc && d[Id] === doc[Id] ? i : l, -1);
+                if (pind !== -1) {
+                    list.splice(pind, 1);
+                }
+            }
+            if (first) {
+                list.splice(0, 0, doc);
+            }
+            else {
+                const ind = relativeTo ? list.indexOf(relativeTo) : -1;
+                if (ind === -1) {
+                    if (reversed) list.splice(0, 0, doc);
+                    else list.push(doc);
+                }
+                else {
+                    if (reversed) list.splice(before ? (list.length - ind) + 1 : list.length - ind, 0, doc);
+                    else list.splice(before ? ind : ind + 1, 0, doc);
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    //
+    // Computes the bounds of the contents of a set of documents.
+    //
+    export function ComputeContentBounds(docList: Doc[]) {
+        const bounds = docList.reduce((bounds, doc) => {
+            const [sptX, sptY] = [NumCast(doc.x), NumCast(doc.y)];
+            const [bptX, bptY] = [sptX + doc[WidthSym](), sptY + doc[HeightSym]()];
+            return {
+                x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
+                r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
+            };
+        }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: -Number.MAX_VALUE, b: -Number.MAX_VALUE });
+        return bounds;
+    }
+
+    export function MakeAlias(doc: Doc, id?: string) {
+        const alias = !GetT(doc, "isPrototype", "boolean", true) ? Doc.MakeCopy(doc, undefined, id) : Doc.MakeDelegate(doc, id);
+        const layout = Doc.LayoutField(alias);
+        if (layout instanceof Doc && layout !== alias && layout === Doc.Layout(alias)) {
+            Doc.SetLayout(alias, Doc.MakeAlias(layout));
+        }
+        alias.aliasOf = doc;
+        alias.title = ComputedField.MakeFunction(`renameAlias(this, ${Doc.GetProto(doc).aliasNumber = NumCast(Doc.GetProto(doc).aliasNumber) + 1})`);
+        return alias;
+    }
+
+    //
+    // Determines whether the layout needs to be expanded (as a template).
+    // template expansion is rquired when the layout is a template doc/field and there's a datadoc which isn't equal to the layout template
+    //
+    export function WillExpandTemplateLayout(layoutDoc: Doc, dataDoc?: Doc) {
+        return (layoutDoc.isTemplateForField || layoutDoc.isTemplateDoc) && dataDoc && layoutDoc !== dataDoc;
+    }
+
+    const _pendingMap: Map<string, boolean> = new Map();
+    //
+    // Returns an expanded template layout for a target data document if there is a template relationship
+    // between the two. If so, the layoutDoc is expanded into a new document that inherits the properties 
+    // of the original layout while allowing for individual layout properties to be overridden in the expanded layout.
+    // templateArgs should be equivalent to the layout key that generates the template since that's where the template parameters are stored in ()'s at the end of the key.
+    // NOTE:  the template will have references to "@params" -- the template arguments will be assigned to the '@params' field
+    // so that when the @params key is accessed, it will be rewritten as the key that is stored in the 'params' field and
+    // the derefence will then occur on the rootDocument (the original document).
+    // in the future, field references could be written as @<someparam> and then arguments would be passed in the layout key as:
+    //   layout_mytemplate(somparam=somearg).   
+    // then any references to @someparam would be rewritten as accesses to 'somearg' on the rootDocument
+    export function expandTemplateLayout(templateLayoutDoc: Doc, targetDoc?: Doc, templateArgs?: string) {
+        const args = templateArgs?.match(/\(([a-zA-Z0-9._\-]*)\)/)?.[1].replace("()", "") || StrCast(templateLayoutDoc.PARAMS);
+        if (!args && !WillExpandTemplateLayout(templateLayoutDoc, targetDoc) || !targetDoc) return templateLayoutDoc;
+
+        const templateField = StrCast(templateLayoutDoc.isTemplateForField);  // the field that the template renders
+        // First it checks if an expanded layout already exists -- if so it will be stored on the dataDoc
+        // using the template layout doc's id as the field key.
+        // If it doesn't find the expanded layout, then it makes a delegate of the template layout and
+        // saves it on the data doc indexed by the template layout's id.
+        //
+        const params = args.split("=").length > 1 ? args.split("=")[0] : "PARAMS";
+        const layoutFielddKey = Doc.LayoutFieldKey(templateLayoutDoc);
+        const expandedLayoutFieldKey = (templateField || layoutFielddKey) + "-layout[" + templateLayoutDoc[Id] + (args ? `(${args})` : "") + "]";
+        let expandedTemplateLayout = targetDoc?.[expandedLayoutFieldKey];
+
+        if (templateLayoutDoc.resolvedDataDoc instanceof Promise) {
+            expandedTemplateLayout = undefined;
+            _pendingMap.set(targetDoc[Id] + expandedLayoutFieldKey, true);
+        }
+        else if (expandedTemplateLayout === undefined && !_pendingMap.get(targetDoc[Id] + expandedLayoutFieldKey + args)) {
+            if (templateLayoutDoc.resolvedDataDoc === (targetDoc.rootDocument || Doc.GetProto(targetDoc)) && templateLayoutDoc.PARAMS === StrCast(targetDoc.PARAMS)) {
+                expandedTemplateLayout = templateLayoutDoc; // reuse an existing template layout if its for the same document with the same params
+            } else {
+                _pendingMap.set(targetDoc[Id] + expandedLayoutFieldKey + args, true);
+                templateLayoutDoc.resolvedDataDoc && (templateLayoutDoc = Cast(templateLayoutDoc.proto, Doc, null) || templateLayoutDoc); // if the template has already been applied (ie, a nested template), then use the template's prototype
+                setTimeout(action(() => {
+                    if (!targetDoc[expandedLayoutFieldKey]) {
+                        const newLayoutDoc = Doc.MakeDelegate(templateLayoutDoc, undefined, "[" + templateLayoutDoc.title + "]");
+                        // the template's arguments are stored in params which is derefenced to find
+                        // the actual field key where the parameterized template data is stored.
+                        newLayoutDoc[params] = args !== "..." ? args : ""; // ... signifies the layout has sub template(s) -- so we have to expand the layout for them so that they can get the correct 'rootDocument' field, but we don't need to reassign their params.  it would be better if the 'rootDocument' field could be passed dynamically to avoid have to create instances
+                        newLayoutDoc.rootDocument = targetDoc;
+                        targetDoc[expandedLayoutFieldKey] = newLayoutDoc;
+                        const dataDoc = Doc.GetProto(targetDoc);
+                        newLayoutDoc.resolvedDataDoc = dataDoc;
+                        if (dataDoc[templateField] === undefined && templateLayoutDoc[templateField] instanceof List) {
+                            dataDoc[templateField] = ComputedField.MakeFunction(`ObjectField.MakeCopy(templateLayoutDoc["${templateField}"] as List)`, { templateLayoutDoc: Doc.name }, { templateLayoutDoc });
+                        }
+                        _pendingMap.delete(targetDoc[Id] + expandedLayoutFieldKey + args);
+                    }
+                }), 0);
+            }
+        }
+        return expandedTemplateLayout instanceof Doc ? expandedTemplateLayout : undefined; // layout is undefined if the expandedTemplateLayout is pending.
+    }
+
+    // if the childDoc is a template for a field, then this will return the expanded layout with its data doc.
+    // otherwise, it just returns the childDoc
+    export function GetLayoutDataDocPair(containerDoc: Doc, containerDataDoc: Opt<Doc>, childDoc: Doc) {
+        if (!childDoc || childDoc instanceof Promise || !Doc.GetProto(childDoc)) {
+            console.log("No, no, no!");
+            return { layout: childDoc, data: childDoc };
+        }
+        const resolvedDataDoc = (Doc.AreProtosEqual(containerDataDoc, containerDoc) || (!childDoc.isTemplateDoc && !childDoc.isTemplateForField && !childDoc.PARAMS) ? undefined : containerDataDoc);
+        return { layout: Doc.expandTemplateLayout(childDoc, resolvedDataDoc, "(" + StrCast(containerDoc.PARAMS) + ")"), data: resolvedDataDoc };
+    }
+
+    export function Overwrite(doc: Doc, overwrite: Doc, copyProto: boolean = false): Doc {
+        Object.keys(doc).forEach(key => {
+            const field = ProxyField.WithoutProxy(() => doc[key]);
+            if (key === "proto" && copyProto) {
+                if (doc.proto instanceof Doc && overwrite.proto instanceof Doc) {
+                    overwrite[key] = Doc.Overwrite(doc[key]!, overwrite.proto);
+                }
+            } else {
+                if (field instanceof RefField) {
+                    overwrite[key] = field;
+                } else if (field instanceof ObjectField) {
+                    overwrite[key] = ObjectField.MakeCopy(field);
+                } else if (field instanceof Promise) {
+                    debugger; //This shouldn't happend...
+                } else {
+                    overwrite[key] = field;
+                }
+            }
+        });
+
+        return overwrite;
+    }
+
+    export function MakeCopy(doc: Doc, copyProto: boolean = false, copyProtoId?: string): Doc {
+        const copy = new Doc(copyProtoId, true);
+        const exclude = Cast(doc.excludeFields, listSpec("string"), []);
+        Object.keys(doc).forEach(key => {
+            if (exclude.includes(key)) return;
+            const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
+            const field = ProxyField.WithoutProxy(() => doc[key]);
+            if (key === "proto" && copyProto) {
+                if (doc[key] instanceof Doc) {
+                    copy[key] = Doc.MakeCopy(doc[key]!, false);
+                }
+            } else {
+                if (field instanceof RefField) {
+                    copy[key] = field;
+                } else if (cfield instanceof ComputedField) {
+                    copy[key] = ComputedField.MakeFunction(cfield.script.originalScript);
+                } else if (field instanceof ObjectField) {
+                    copy[key] = doc[key] instanceof Doc ?
+                        key.includes("layout[") ? Doc.MakeCopy(doc[key] as Doc, false) : doc[key] : // reference documents except copy documents that are expanded teplate fields 
+                        ObjectField.MakeCopy(field);
+                } else if (field instanceof Promise) {
+                    debugger; //This shouldn't happend...
+                } else {
+                    copy[key] = field;
+                }
+            }
+        });
+
+        return copy;
+    }
+
+    export function MakeClone(doc: Doc): Doc {
+        const cloneMap = new Map<string, Doc>();
+        const rtfMap: { copy: Doc, key: string, field: RichTextField }[] = [];
+        const copy = Doc.makeClone(doc, cloneMap, rtfMap);
+        rtfMap.map(({ copy, key, field }) => {
+            const replacer = (match: any, attr: string, id: string, offset: any, string: any) => {
+                const mapped = cloneMap.get(id);
+                return attr + "\"" + (mapped ? mapped[Id] : id) + "\"";
+            };
+            const replacer2 = (match: any, href: string, id: string, offset: any, string: any) => {
+                const mapped = cloneMap.get(id);
+                return href + (mapped ? mapped[Id] : id);
+            };
+            const regex = `(${Utils.prepend("/doc/")})([^"]*)`;
+            const re = new RegExp(regex, "g");
+            copy[key] = new RichTextField(field.Data.replace(/("docid":|"targetId":|"linkId":)"([^"]+)"/g, replacer).replace(re, replacer2), field.Text);
+        });
+        return copy;
+    }
+
+    export function makeClone(doc: Doc, cloneMap: Map<string, Doc>, rtfs: { copy: Doc, key: string, field: RichTextField }[]): Doc {
+        if (Doc.IsBaseProto(doc)) return doc;
+        if (cloneMap.get(doc[Id])) return cloneMap.get(doc[Id])!;
+        const copy = new Doc(undefined, true);
+        cloneMap.set(doc[Id], copy);
+        if (LinkManager.Instance.getAllLinks().includes(doc) && LinkManager.Instance.getAllLinks().indexOf(copy) === -1) LinkManager.Instance.addLink(copy);
+        const exclude = Cast(doc.excludeFields, listSpec("string"), []);
+        Object.keys(doc).forEach(key => {
+            if (exclude.includes(key)) return;
+            const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
+            const field = ProxyField.WithoutProxy(() => doc[key]);
+            const copyObjectField = (field: ObjectField) => {
+                const list = Cast(doc[key], listSpec(Doc));
+                if (list !== undefined && !(list instanceof Promise)) {
+                    copy[key] = new List<Doc>(list.filter(d => d instanceof Doc).map(d => Doc.makeClone(d as Doc, cloneMap, rtfs)));
+                } else if (doc[key] instanceof Doc) {
+                    copy[key] = key.includes("layout[") ? undefined : Doc.makeClone(doc[key] as Doc, cloneMap, rtfs); // reference documents except copy documents that are expanded teplate fields 
+                } else {
+                    copy[key] = ObjectField.MakeCopy(field);
+                    if (field instanceof RichTextField) {
+                        if (field.Data.includes('"docid":') || field.Data.includes('"targetId":') || field.Data.includes('"linkId":')) {
+                            rtfs.push({ copy, key, field });
+                        }
+                    }
+                }
+            };
+            if (key === "proto") {
+                if (doc[key] instanceof Doc) {
+                    copy[key] = Doc.makeClone(doc[key]!, cloneMap, rtfs);
+                }
+            } else {
+                if (field instanceof RefField) {
+                    copy[key] = field;
+                } else if (cfield instanceof ComputedField) {
+                    copy[key] = ComputedField.MakeFunction(cfield.script.originalScript);
+                    (key === "links" && field instanceof ObjectField) && copyObjectField(field);
+                } else if (field instanceof ObjectField) {
+                    copyObjectField(field);
+                } else if (field instanceof Promise) {
+                    debugger; //This shouldn't happend...
+                } else {
+                    copy[key] = field;
+                }
+            }
+        });
+        Doc.SetInPlace(copy, "title", "CLONE: " + doc.title, true);
+        copy.cloneOf = doc;
+        cloneMap.set(doc[Id], copy);
+        return copy;
+    }
+
+    export function MakeDelegate(doc: Doc, id?: string, title?: string): Doc;
+    export function MakeDelegate(doc: Opt<Doc>, id?: string, title?: string): Opt<Doc>;
+    export function MakeDelegate(doc: Opt<Doc>, id?: string, title?: string): Opt<Doc> {
+        if (doc) {
+            const delegate = new Doc(id, true);
+            delegate.proto = doc;
+            title && (delegate.title = title);
+            return delegate;
+        }
+        return undefined;
+    }
+
+    let _applyCount: number = 0;
+    export function ApplyTemplate(templateDoc: Doc) {
+        if (templateDoc) {
+            const target = Doc.MakeDelegate(new Doc());
+            const targetKey = StrCast(templateDoc.layoutKey, "layout");
+            const applied = ApplyTemplateTo(templateDoc, target, targetKey, templateDoc.title + "(..." + _applyCount++ + ")");
+            target.layoutKey = targetKey;
+            applied && (Doc.GetProto(applied).type = templateDoc.type);
+            return applied;
+        }
+        return undefined;
+    }
+    export function ApplyTemplateTo(templateDoc: Doc, target: Doc, targetKey: string, titleTarget: string | undefined) {
+        if (!Doc.AreProtosEqual(target[targetKey] as Doc, templateDoc)) {
+            if (target.resolvedDataDoc) {
+                target[targetKey] = new PrefetchProxy(templateDoc);
+            } else {
+                titleTarget && (Doc.GetProto(target).title = titleTarget);
+                Doc.GetProto(target)[targetKey] = new PrefetchProxy(templateDoc);
+            }
+        }
+        return target;
+    }
+
+    //
+    //  This function converts a generic field layout display into a field layout that displays a specific
+    // metadata field indicated by the title of the template field (not the default field that it was rendering)
+    //
+    export function MakeMetadataFieldTemplate(templateField: Doc, templateDoc: Opt<Doc>): boolean {
+
+        // find the metadata field key that this template field doc will display (indicated by its title)
+        const metadataFieldKey = StrCast(templateField.isTemplateForField) || StrCast(templateField.title).replace(/^-/, "");
+
+        // update the original template to mark it as a template
+        templateField.isTemplateForField = metadataFieldKey;
+        templateField.title = metadataFieldKey;
+
+        const templateFieldValue = templateField[metadataFieldKey] || templateField[Doc.LayoutFieldKey(templateField)];
+        const templateCaptionValue = templateField.caption;
+        // move any data that the template field had been rendering over to the template doc so that things will still be rendered
+        // when the template field is adjusted to point to the new metadatafield key.
+        // note 1: if the template field contained a list of documents, each of those documents will be converted to templates as well.
+        // note 2: this will not overwrite any field that already exists on the template doc at the field key
+        if (!templateDoc?.[metadataFieldKey] && templateFieldValue instanceof ObjectField) {
+            Cast(templateFieldValue, listSpec(Doc), [])?.map(d => d instanceof Doc && MakeMetadataFieldTemplate(d, templateDoc));
+            (Doc.GetProto(templateField)[metadataFieldKey] = ObjectField.MakeCopy(templateFieldValue));
+        }
+        // copy the textTemplates from 'this' (not 'self') because the layout contains the template info, not the original doc
+        if (templateCaptionValue instanceof RichTextField && !templateCaptionValue.Empty()) {
+            templateField["caption-textTemplate"] = ComputedField.MakeFunction(`copyField(this.caption)`);
+        }
+        if (templateFieldValue instanceof RichTextField && !templateFieldValue.Empty()) {
+            templateField[metadataFieldKey + "-textTemplate"] = ComputedField.MakeFunction(`copyField(this.${metadataFieldKey})`);
+        }
+
+        // get the layout string that the template uses to specify its layout
+        const templateFieldLayoutString = StrCast(Doc.LayoutField(Doc.Layout(templateField)));
+
+        // change it to render the target metadata field instead of what it was rendering before and assign it to the template field layout document.
+        Doc.Layout(templateField).layout = templateFieldLayoutString.replace(/fieldKey={'[^']*'}/, `fieldKey={'${metadataFieldKey}'}`);
+
+        // assign the template field doc a delegate of any extension document that was previously used to render the template field (since extension doc's carry rendering informatino)
+        Doc.Layout(templateField)[metadataFieldKey + "_ext"] = Doc.MakeDelegate(templateField[templateFieldLayoutString?.split("'")[1] + "_ext"] as Doc);
+
+        return true;
+    }
+
+    export function overlapping(doc1: Doc, doc2: Doc, clusterDistance: number) {
+        const doc2Layout = Doc.Layout(doc2);
+        const doc1Layout = Doc.Layout(doc1);
+        const x2 = NumCast(doc2.x) - clusterDistance;
+        const y2 = NumCast(doc2.y) - clusterDistance;
+        const w2 = NumCast(doc2Layout._width) + clusterDistance;
+        const h2 = NumCast(doc2Layout._height) + clusterDistance;
+        const x = NumCast(doc1.x) - clusterDistance;
+        const y = NumCast(doc1.y) - clusterDistance;
+        const w = NumCast(doc1Layout._width) + clusterDistance;
+        const h = NumCast(doc1Layout._height) + clusterDistance;
+        return doc1.z === doc2.z && intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 });
+    }
+
+    export function isBrushedHighlightedDegree(doc: Doc) {
+        if (Doc.IsHighlighted(doc)) {
+            return 6;
+        }
+        else {
+            return Doc.IsBrushedDegree(doc);
+        }
+    }
+
+    export class DocBrush {
+        BrushedDoc: ObservableMap<Doc, boolean> = new ObservableMap();
+    }
+    const brushManager = new DocBrush();
+
+    export class DocData {
+        @observable _user_doc: Doc = undefined!;
+        @observable _searchQuery: string = "";
+    }
+
+    // the document containing the view layout information - will be the Document itself unless the Document has
+    // a layout field or 'layout' is given.  
+    export function Layout(doc: Doc, layout?: Doc): Doc {
+        const overrideLayout = layout && Cast(doc[`${StrCast(layout.isTemplateForField, "data")}-layout[` + layout[Id] + "]"], Doc, null);
+        return overrideLayout || doc[LayoutSym] || doc;
+    }
+    export function SetLayout(doc: Doc, layout: Doc | string) { doc[StrCast(doc.layoutKey, "layout")] = layout; }
+    export function LayoutField(doc: Doc) { return doc[StrCast(doc.layoutKey, "layout")]; }
+    export function LayoutFieldKey(doc: Doc): string { return StrCast(Doc.Layout(doc).layout).split("'")[1]; }
+    const manager = new DocData();
+    export function SearchQuery(): string { return manager._searchQuery; }
+    export function SetSearchQuery(query: string) { runInAction(() => manager._searchQuery = query); }
+    export function UserDoc(): Doc { return manager._user_doc; }
+    export function SetUserDoc(doc: Doc) { manager._user_doc = doc; }
+    export function IsBrushed(doc: Doc) {
+        return computedFn(function IsBrushed(doc: Doc) {
+            return brushManager.BrushedDoc.has(doc) || brushManager.BrushedDoc.has(Doc.GetProto(doc));
+        })(doc);
+    }
+    // don't bother memoizing (caching) the result if called from a non-reactive context. (plus this avoids a warning message)
+    export function IsBrushedDegreeUnmemoized(doc: Doc) {
+        return brushManager.BrushedDoc.has(doc) ? 2 : brushManager.BrushedDoc.has(Doc.GetProto(doc)) ? 1 : 0;
+    }
+    export function IsBrushedDegree(doc: Doc) {
+        return computedFn(function IsBrushDegree(doc: Doc) {
+            return Doc.IsBrushedDegreeUnmemoized(doc);
+        })(doc);
+    }
+    export function BrushDoc(doc: Doc) {
+        brushManager.BrushedDoc.set(doc, true);
+        brushManager.BrushedDoc.set(Doc.GetProto(doc), true);
+        return doc;
+    }
+    export function UnBrushDoc(doc: Doc) {
+        brushManager.BrushedDoc.delete(doc);
+        brushManager.BrushedDoc.delete(Doc.GetProto(doc));
+        return doc;
+    }
+
+
+    export function LinkOtherAnchor(linkDoc: Doc, anchorDoc: Doc) { return Doc.AreProtosEqual(anchorDoc, Cast(linkDoc.anchor1, Doc) as Doc) ? Cast(linkDoc.anchor2, Doc) as Doc : Cast(linkDoc.anchor1, Doc) as Doc; }
+    export function LinkEndpoint(linkDoc: Doc, anchorDoc: Doc) { return Doc.AreProtosEqual(anchorDoc, Cast(linkDoc.anchor1, Doc) as Doc) ? "1" : "2"; }
+
+    export function linkFollowUnhighlight() {
+        Doc.UnhighlightAll();
+        document.removeEventListener("pointerdown", linkFollowUnhighlight);
+    }
+
+    let _lastDate = 0;
+    export function linkFollowHighlight(destDoc: Doc, dataAndDisplayDocs = true) {
+        linkFollowUnhighlight();
+        Doc.HighlightDoc(destDoc, dataAndDisplayDocs);
+        document.removeEventListener("pointerdown", linkFollowUnhighlight);
+        document.addEventListener("pointerdown", linkFollowUnhighlight);
+        const lastDate = _lastDate = Date.now();
+        window.setTimeout(() => _lastDate === lastDate && linkFollowUnhighlight(), 5000);
+    }
+
+    export class HighlightBrush {
+        @observable HighlightedDoc: Map<Doc, boolean> = new Map();
+    }
+    const highlightManager = new HighlightBrush();
+    export function IsHighlighted(doc: Doc) {
+        return highlightManager.HighlightedDoc.get(doc) || highlightManager.HighlightedDoc.get(Doc.GetProto(doc));
+    }
+    export function HighlightDoc(doc: Doc, dataAndDisplayDocs = true) {
+        runInAction(() => {
+            highlightManager.HighlightedDoc.set(doc, true);
+            dataAndDisplayDocs && highlightManager.HighlightedDoc.set(Doc.GetProto(doc), true);
+        });
+    }
+    export function UnHighlightDoc(doc: Doc) {
+        runInAction(() => {
+            highlightManager.HighlightedDoc.set(doc, false);
+            highlightManager.HighlightedDoc.set(Doc.GetProto(doc), false);
+        });
+    }
+    export function UnhighlightAll() {
+        const mapEntries = highlightManager.HighlightedDoc.keys();
+        let docEntry: IteratorResult<Doc>;
+        while (!(docEntry = mapEntries.next()).done) {
+            const targetDoc = docEntry.value;
+            targetDoc && Doc.UnHighlightDoc(targetDoc);
+        }
+
+    }
+    export function UnBrushAllDocs() {
+        brushManager.BrushedDoc.clear();
+    }
+
+    export function getDocTemplate(doc?: Doc) {
+        return doc?.isTemplateDoc ? doc :
+            Cast(doc?.dragFactory, Doc, null)?.isTemplateDoc ? doc?.dragFactory :
+                Cast(doc?.layout, Doc, null)?.isTemplateDoc ? doc?.layout : undefined;
+    }
+
+    export function matchFieldValue(doc: Doc, key: string, value: any): boolean {
+        const fieldVal = doc[key];
+        if (Cast(fieldVal, listSpec("string"), []).length) {
+            const vals = Cast(fieldVal, listSpec("string"), []);
+            return vals.some(v => v === value);
+        }
+        const fieldStr = Field.toString(fieldVal as Field);
+        return fieldStr === value;
+    }
+
+    export function deiconifyView(doc: any) {
+        StrCast(doc.layoutKey).split("_")[1] === "icon" && setNativeView(doc);
+    }
+
+    export function setNativeView(doc: any) {
+        const prevLayout = StrCast(doc.layoutKey).split("_")[1];
+        const deiconify = prevLayout === "icon" && StrCast(doc.deiconifyLayout) ? "layout_" + StrCast(doc.deiconifyLayout) : "";
+        prevLayout === "icon" && (doc.deiconifyLayout = undefined);
+        doc.layoutKey = deiconify || "layout";
+    }
+    export function setDocFilterRange(target: Doc, key: string, range?: number[]) {
+        const docRangeFilters = Cast(target._docRangeFilters, listSpec("string"), []);
+        for (let i = 0; i < docRangeFilters.length; i += 3) {
+            if (docRangeFilters[i] === key) {
+                docRangeFilters.splice(i, 3);
+                break;
+            }
+        }
+        if (range !== undefined) {
+            docRangeFilters.push(key);
+            docRangeFilters.push(range[0].toString());
+            docRangeFilters.push(range[1].toString());
+            target._docRangeFilters = new List<string>(docRangeFilters);
+        }
+    }
+
+    export function aliasDocs(field: any) {
+        return new List<Doc>(field.map((d: any) => Doc.MakeAlias(d)));
+    }
+
+    // filters document in a container collection:
+    // all documents with the specified value for the specified key are included/excluded 
+    // based on the modifiers :"check", "x", undefined
+    export function setDocFilter(container: Doc, key: string, value: any, modifiers?: "check" | "x" | undefined) {
+        const docFilters = Cast(container._docFilters, listSpec("string"), []);
+        for (let i = 0; i < docFilters.length; i += 3) {
+            if (docFilters[i] === key && docFilters[i + 1] === value) {
+                docFilters.splice(i, 3);
+                break;
+            }
+        }
+        if (typeof modifiers === "string") {
+            docFilters.push(key);
+            docFilters.push(value);
+            docFilters.push(modifiers);
+            container._docFilters = new List<string>(docFilters);
+        }
+    }
+    export function readDocRangeFilter(doc: Doc, key: string) {
+        const docRangeFilters = Cast(doc._docRangeFilters, listSpec("string"), []);
+        for (let i = 0; i < docRangeFilters.length; i += 3) {
+            if (docRangeFilters[i] === key) {
+                return [Number(docRangeFilters[i + 1]), Number(docRangeFilters[i + 2])];
+            }
+        }
+    }
+    export function assignDocToField(doc: Doc, field: string, id: string) {
+        DocServer.GetRefField(id).then(layout => layout instanceof Doc && (doc[field] = layout));
+        return id;
+    }
+
+    export function toggleNativeDimensions(layoutDoc: Doc, contentScale: number, panelWidth: number, panelHeight: number) {
+        runInAction(() => {
+            if (layoutDoc._nativeWidth || layoutDoc._nativeHeight) {
+                layoutDoc.scale = NumCast(layoutDoc.scale, 1) * contentScale;
+                layoutDoc._nativeWidth = undefined;
+                layoutDoc._nativeHeight = undefined;
+            }
+            else {
+                layoutDoc._autoHeight = false;
+                if (!layoutDoc._nativeWidth) {
+                    layoutDoc._nativeWidth = NumCast(layoutDoc._width, panelWidth);
+                    layoutDoc._nativeHeight = NumCast(layoutDoc._height, panelHeight);
+                }
+            }
+        });
+    }
+
+    export function isDocPinned(doc: Doc) {
+        //add this new doc to props.Document
+        const curPres = Cast(Doc.UserDoc().activePresentation, Doc) as Doc;
+        if (curPres) {
+            return DocListCast(curPres.data).findIndex((val) => Doc.AreProtosEqual(val, doc)) !== -1;
+        }
+        return false;
+    }
+
+    // applies a custom template to a document.  the template is identified by it's short name (e.g, slideView not layout_slideView)
+    export function makeCustomViewClicked(doc: Doc, creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, templateSignature: string = "custom", docLayoutTemplate?: Doc) {
+        const batch = UndoManager.StartBatch("makeCustomViewClicked");
+        runInAction(() => {
+            doc.layoutKey = "layout_" + templateSignature;
+            if (doc[doc.layoutKey] === undefined) {
+                createCustomView(doc, creator, templateSignature, docLayoutTemplate);
+            }
+        });
+        batch.end();
+    }
+    export function findTemplate(templateName: string, type: string, signature: string) {
+        let docLayoutTemplate: Opt<Doc>;
+        const iconViews = DocListCast(Cast(Doc.UserDoc()["template-icons"], Doc, null)?.data);
+        const templBtns = DocListCast(Cast(Doc.UserDoc()["template-buttons"], Doc, null)?.data);
+        const noteTypes = DocListCast(Cast(Doc.UserDoc()["template-notes"], Doc, null)?.data);
+        const clickFuncs = DocListCast(Cast(Doc.UserDoc().clickFuncs, Doc, null)?.data);
+        const allTemplates = iconViews.concat(templBtns).concat(noteTypes).concat(clickFuncs).map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc);
+        // bcz: this is hacky -- want to have different templates be applied depending on the "type" of a document.  but type is not reliable and there could be other types of template searches so this should be generalized
+        // first try to find a template that matches the specific document type (<typeName>_<templateName>).  otherwise, fallback to a general match on <templateName>
+        !docLayoutTemplate && allTemplates.forEach(tempDoc => StrCast(tempDoc.title) === templateName + "_" + type && (docLayoutTemplate = tempDoc));
+        !docLayoutTemplate && allTemplates.forEach(tempDoc => StrCast(tempDoc.title) === templateName && (docLayoutTemplate = tempDoc));
+        return docLayoutTemplate;
+    }
+    export function createCustomView(doc: Doc, creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, templateSignature: string = "custom", docLayoutTemplate?: Doc) {
+        const templateName = templateSignature.replace(/\(.*\)/, "");
+        docLayoutTemplate = docLayoutTemplate || findTemplate(templateName, StrCast(doc.type), templateSignature);
+
+        const customName = "layout_" + templateSignature;
+        const _width = NumCast(doc._width);
+        const _height = NumCast(doc._height);
+        const options = { title: "data", backgroundColor: StrCast(doc.backgroundColor), _autoHeight: true, _width, x: -_width / 2, y: - _height / 2, _showSidebar: false };
+
+        let fieldTemplate: Opt<Doc>;
+        if (doc.data instanceof RichTextField || typeof (doc.data) === "string") {
+            fieldTemplate = Docs.Create.TextDocument("", options);
+        } else if (doc.data instanceof PdfField) {
+            fieldTemplate = Docs.Create.PdfDocument("http://www.msn.com", options);
+        } else if (doc.data instanceof VideoField) {
+            fieldTemplate = Docs.Create.VideoDocument("http://www.cs.brown.edu", options);
+        } else if (doc.data instanceof AudioField) {
+            fieldTemplate = Docs.Create.AudioDocument("http://www.cs.brown.edu", options);
+        } else if (doc.data instanceof ImageField) {
+            fieldTemplate = Docs.Create.ImageDocument("http://www.cs.brown.edu", options);
+        }
+        const docTemplate = docLayoutTemplate || creator?.(fieldTemplate ? [fieldTemplate] : [], { title: customName + "(" + doc.title + ")", isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) });
+
+        fieldTemplate && Doc.MakeMetadataFieldTemplate(fieldTemplate, docTemplate ? Doc.GetProto(docTemplate) : docTemplate);
+        docTemplate && Doc.ApplyTemplateTo(docTemplate, doc, customName, undefined);
+    }
+    export function makeCustomView(doc: Doc, custom: boolean, layout: string) {
+        Doc.setNativeView(doc);
+        if (custom) {
+            makeCustomViewClicked(doc, Docs.Create.StackingDocument, layout, undefined);
+        }
+    }
+    export function iconify(doc: Doc) {
+        const layoutKey = Cast(doc.layoutKey, "string", null);
+        Doc.makeCustomViewClicked(doc, Docs.Create.StackingDocument, "icon", undefined);
+        if (layoutKey && layoutKey !== "layout" && layoutKey !== "layout_icon") doc.deiconifyLayout = layoutKey.replace("layout_", "");
+    }
+
+    export function pileup(selected: Doc[], x: number, y: number) {
+        const newCollection = Docs.Create.PileDocument(selected, { title: "pileup", x: x - 55, y: y - 55, _width: 110, _height: 100, _LODdisable: true });
+        let w = 0, h = 0;
+        selected.forEach((d, i) => {
+            Doc.iconify(d);
+            w = Math.max(d[WidthSym](), w);
+            h = Math.max(d[HeightSym](), h);
+        });
+        h = Math.max(h, w * 4 / 3); // converting to an icon does not update the height right away.  so this is a fallback hack to try to do something reasonable
+        selected.forEach((d, i) => {
+            d.x = Math.cos(Math.PI * 2 * i / selected.length) * 10 - w / 2;
+            d.y = Math.sin(Math.PI * 2 * i / selected.length) * 10 - h / 2;
+            d.displayTimecode = undefined;  // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
+        });
+        newCollection.x = NumCast(newCollection.x) + NumCast(newCollection._width) / 2 - 55;
+        newCollection.y = NumCast(newCollection.y) + NumCast(newCollection._height) / 2 - 55;
+        newCollection._width = newCollection._height = 110;
+        //newCollection.borderRounding = "40px";
+        newCollection._jitterRotation = 10;
+        newCollection._backgroundColor = "gray";
+        newCollection._overflow = "visible";
+        return newCollection;
+    }
+
+
+    export async function addFieldEnumerations(doc: Opt<Doc>, enumeratedFieldKey: string, enumerations: { title: string, _backgroundColor?: string, color?: string }[]) {
+        let optionsCollection = await DocServer.GetRefField(enumeratedFieldKey);
+        if (!(optionsCollection instanceof Doc)) {
+            optionsCollection = Docs.Create.StackingDocument([], { title: `${enumeratedFieldKey} field set` }, enumeratedFieldKey);
+            Doc.AddDocToList((Doc.UserDoc().fieldTypes as Doc), "data", optionsCollection as Doc);
+        }
+        const options = optionsCollection as Doc;
+        const targetDoc = doc && Doc.GetProto(Cast(doc.rootDocument, Doc, null) || doc);
+        const docFind = `options.data.find(doc => doc.title === (this.rootDocument||this)["${enumeratedFieldKey}"])?`;
+        targetDoc && (targetDoc.backgroundColor = ComputedField.MakeFunction(docFind + `._backgroundColor || "white"`, undefined, { options }));
+        targetDoc && (targetDoc.color = ComputedField.MakeFunction(docFind + `.color || "black"`, undefined, { options }));
+        targetDoc && (targetDoc.borderRounding = ComputedField.MakeFunction(docFind + `.borderRounding`, undefined, { options }));
+        enumerations.map(enumeration => {
+            const found = DocListCast(options.data).find(d => d.title === enumeration.title);
+            if (found) {
+                found._backgroundColor = enumeration._backgroundColor || found._backgroundColor;
+                found._color = enumeration.color || found._color;
+            } else {
+                Doc.AddDocToList(options, "data", Docs.Create.TextDocument(enumeration.title, enumeration));
+            }
+        });
+        return optionsCollection;
+    }
+}
+
+Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(Doc.GetProto(doc).title).replace(/\([0-9]*\)/, "") + `(${n})`; });
+Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); });
+Scripting.addGlobal(function getDocTemplate(doc?: any) { return Doc.getDocTemplate(doc); });
+Scripting.addGlobal(function getAlias(doc: any) { return Doc.MakeAlias(doc); });
+Scripting.addGlobal(function getCopy(doc: any, copyProto: any) { return doc.isTemplateDoc ? Doc.ApplyTemplate(doc) : Doc.MakeCopy(doc, copyProto); });
+Scripting.addGlobal(function copyField(field: any) { return ObjectField.MakeCopy(field); });
+Scripting.addGlobal(function aliasDocs(field: any) { return Doc.aliasDocs(field); });
+Scripting.addGlobal(function docList(field: any) { return DocListCast(field); });
+Scripting.addGlobal(function setInPlace(doc: any, field: any, value: any) { return Doc.SetInPlace(doc, field, value, false); });
+Scripting.addGlobal(function sameDocs(doc1: any, doc2: any) { return Doc.AreProtosEqual(doc1, doc2); });
+Scripting.addGlobal(function deiconifyView(doc: any) { Doc.deiconifyView(doc); });
+Scripting.addGlobal(function undo() { return UndoManager.Undo(); });
+Scripting.addGlobal(function redo() { return UndoManager.Redo(); });
+Scripting.addGlobal(function DOC(id: string) { console.log("Can't parse a document id in a script"); return "invalid"; });
+Scripting.addGlobal(function assignDoc(doc: Doc, field: string, id: string) { return Doc.assignDocToField(doc, field, id); });
+Scripting.addGlobal(function docCast(doc: FieldResult): any { return DocCastAsync(doc); });
+Scripting.addGlobal(function activePresentationItem() {
+    const curPres = Doc.UserDoc().activePresentation as Doc;
+    return curPres && DocListCast(curPres[Doc.LayoutFieldKey(curPres)])[NumCast(curPres._itemIndex)];
+});
+Scripting.addGlobal(function selectDoc(doc: any) { Doc.UserDoc().activeSelection = new List([doc]); });
+Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) {
+    const docs = DocListCast(Doc.UserDoc().activeSelection).
+        filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.DOCHOLDER && d.type !== DocumentType.KVP &&
+            (!excludeCollections || d.type !== DocumentType.COL || !Cast(d.data, listSpec(Doc), null)));
+    return docs.length ? new List(docs) : prevValue;
+});
+Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: any, modifiers?: "check" | "x" | undefined) { Doc.setDocFilter(container, key, value, modifiers); });
+Scripting.addGlobal(function setDocFilterRange(container: Doc, key: string, range: number[]) { Doc.setDocFilterRange(container, key, range); });
\ No newline at end of file
diff --git a/src/fields/FieldSymbols.ts b/src/fields/FieldSymbols.ts
new file mode 100644
index 000000000..8d040f493
--- /dev/null
+++ b/src/fields/FieldSymbols.ts
@@ -0,0 +1,12 @@
+
+export const Update = Symbol("Update");
+export const Self = Symbol("Self");
+export const SelfProxy = Symbol("SelfProxy");
+export const HandleUpdate = Symbol("HandleUpdate");
+export const Id = Symbol("Id");
+export const OnUpdate = Symbol("OnUpdate");
+export const Parent = Symbol("Parent");
+export const Copy = Symbol("Copy");
+export const ToScriptString = Symbol("ToScriptString");
+export const ToPlainText = Symbol("ToPlainText");
+export const ToString = Symbol("ToString");
diff --git a/src/fields/HtmlField.ts b/src/fields/HtmlField.ts
new file mode 100644
index 000000000..6e8bba977
--- /dev/null
+++ b/src/fields/HtmlField.ts
@@ -0,0 +1,26 @@
+import { Deserializable } from "../client/util/SerializationHelper";
+import { serializable, primitive } from "serializr";
+import { ObjectField } from "./ObjectField";
+import { Copy, ToScriptString, ToString} from "./FieldSymbols";
+
+@Deserializable("html")
+export class HtmlField extends ObjectField {
+    @serializable(primitive())
+    readonly html: string;
+
+    constructor(html: string) {
+        super();
+        this.html = html;
+    }
+
+    [Copy]() {
+        return new HtmlField(this.html);
+    }
+
+    [ToScriptString]() {
+        return "invalid";
+    }
+    [ToString]() {
+        return this.html;
+    }
+}
diff --git a/src/fields/IconField.ts b/src/fields/IconField.ts
new file mode 100644
index 000000000..76c4ddf1b
--- /dev/null
+++ b/src/fields/IconField.ts
@@ -0,0 +1,26 @@
+import { Deserializable } from "../client/util/SerializationHelper";
+import { serializable, primitive } from "serializr";
+import { ObjectField } from "./ObjectField";
+import { Copy, ToScriptString, ToString } from "./FieldSymbols";
+
+@Deserializable("icon")
+export class IconField extends ObjectField {
+    @serializable(primitive())
+    readonly icon: string;
+
+    constructor(icon: string) {
+        super();
+        this.icon = icon;
+    }
+
+    [Copy]() {
+        return new IconField(this.icon);
+    }
+
+    [ToScriptString]() {
+        return "invalid";
+    }
+    [ToString]() {
+        return "ICONfield";
+    }
+}
diff --git a/src/fields/InkField.ts b/src/fields/InkField.ts
new file mode 100644
index 000000000..bb93de5ac
--- /dev/null
+++ b/src/fields/InkField.ts
@@ -0,0 +1,50 @@
+import { Deserializable } from "../client/util/SerializationHelper";
+import { serializable, custom, createSimpleSchema, list, object, map } from "serializr";
+import { ObjectField } from "./ObjectField";
+import { Copy, ToScriptString, ToString } from "./FieldSymbols";
+
+export enum InkTool {
+    None,
+    Pen,
+    Highlighter,
+    Eraser,
+    Stamp
+}
+
+export interface PointData {
+    X: number;
+    Y: number;
+}
+
+export type InkData = Array<PointData>;
+
+const pointSchema = createSimpleSchema({
+    X: true, Y: true
+});
+
+const strokeDataSchema = createSimpleSchema({
+    pathData: list(object(pointSchema)),
+    "*": true
+});
+
+@Deserializable("ink")
+export class InkField extends ObjectField {
+    @serializable(list(object(strokeDataSchema)))
+    readonly inkData: InkData;
+
+    constructor(data: InkData) {
+        super();
+        this.inkData = data;
+    }
+
+    [Copy]() {
+        return new InkField(this.inkData);
+    }
+
+    [ToScriptString]() {
+        return "invalid";
+    }
+    [ToString]() {
+        return "InkField";
+    }
+}
diff --git a/src/fields/List.ts b/src/fields/List.ts
new file mode 100644
index 000000000..fdabea365
--- /dev/null
+++ b/src/fields/List.ts
@@ -0,0 +1,330 @@
+import { Deserializable, autoObject, afterDocDeserialize } from "../client/util/SerializationHelper";
+import { Field } from "./Doc";
+import { setter, getter, deleteProperty, updateFunction } from "./util";
+import { serializable, alias, list } from "serializr";
+import { observable, action, runInAction } from "mobx";
+import { ObjectField } from "./ObjectField";
+import { RefField } from "./RefField";
+import { ProxyField } from "./Proxy";
+import { Self, Update, Parent, OnUpdate, SelfProxy, ToScriptString, ToString, Copy, Id } from "./FieldSymbols";
+import { Scripting } from "../client/util/Scripting";
+import { DocServer } from "../client/DocServer";
+
+const listHandlers: any = {
+    /// Mutator methods
+    copyWithin() {
+        throw new Error("copyWithin not supported yet");
+    },
+    fill(value: any, start?: number, end?: number) {
+        if (value instanceof RefField) {
+            throw new Error("fill with RefFields not supported yet");
+        }
+        const res = this[Self].__fields.fill(value, start, end);
+        this[Update]();
+        return res;
+    },
+    pop(): any {
+        const field = toRealField(this[Self].__fields.pop());
+        this[Update]();
+        return field;
+    },
+    push: action(function (this: any, ...items: any[]) {
+        items = items.map(toObjectField);
+        const list = this[Self];
+        const length = list.__fields.length;
+        for (let i = 0; i < items.length; i++) {
+            const item = items[i];
+            //TODO Error checking to make sure parent doesn't already exist
+            if (item instanceof ObjectField) {
+                item[Parent] = list;
+                item[OnUpdate] = updateFunction(list, i + length, item, this);
+            }
+        }
+        const res = list.__fields.push(...items);
+        this[Update]();
+        return res;
+    }),
+    reverse() {
+        const res = this[Self].__fields.reverse();
+        this[Update]();
+        return res;
+    },
+    shift() {
+        const res = toRealField(this[Self].__fields.shift());
+        this[Update]();
+        return res;
+    },
+    sort(cmpFunc: any) {
+        this[Self].__realFields(); // coerce retrieving entire array
+        const res = this[Self].__fields.sort(cmpFunc ? (first: any, second: any) => cmpFunc(toRealField(first), toRealField(second)) : undefined);
+        this[Update]();
+        return res;
+    },
+    splice: action(function (this: any, start: number, deleteCount: number, ...items: any[]) {
+        this[Self].__realFields(); // coerce retrieving entire array
+        items = items.map(toObjectField);
+        const list = this[Self];
+        for (let i = 0; i < items.length; i++) {
+            const item = items[i];
+            //TODO Error checking to make sure parent doesn't already exist
+            //TODO Need to change indices of other fields in array
+            if (item instanceof ObjectField) {
+                item[Parent] = list;
+                item[OnUpdate] = updateFunction(list, i + start, item, this);
+            }
+        }
+        const res = list.__fields.splice(start, deleteCount, ...items);
+        this[Update]();
+        return res.map(toRealField);
+    }),
+    unshift(...items: any[]) {
+        items = items.map(toObjectField);
+        const list = this[Self];
+        const length = list.__fields.length;
+        for (let i = 0; i < items.length; i++) {
+            const item = items[i];
+            //TODO Error checking to make sure parent doesn't already exist
+            //TODO Need to change indices of other fields in array
+            if (item instanceof ObjectField) {
+                item[Parent] = list;
+                item[OnUpdate] = updateFunction(list, i, item, this);
+            }
+        }
+        const res = this[Self].__fields.unshift(...items);
+        this[Update]();
+        return res;
+
+    },
+    /// Accessor methods
+    concat: action(function (this: any, ...items: any[]) {
+        this[Self].__realFields();
+        return this[Self].__fields.map(toRealField).concat(...items);
+    }),
+    includes(valueToFind: any, fromIndex: number) {
+        if (valueToFind instanceof RefField) {
+            return this[Self].__realFields().includes(valueToFind, fromIndex);
+        } else {
+            return this[Self].__fields.includes(valueToFind, fromIndex);
+        }
+    },
+    indexOf(valueToFind: any, fromIndex: number) {
+        if (valueToFind instanceof RefField) {
+            return this[Self].__realFields().indexOf(valueToFind, fromIndex);
+        } else {
+            return this[Self].__fields.indexOf(valueToFind, fromIndex);
+        }
+    },
+    join(separator: any) {
+        this[Self].__realFields();
+        return this[Self].__fields.map(toRealField).join(separator);
+    },
+    lastIndexOf(valueToFind: any, fromIndex: number) {
+        if (valueToFind instanceof RefField) {
+            return this[Self].__realFields().lastIndexOf(valueToFind, fromIndex);
+        } else {
+            return this[Self].__fields.lastIndexOf(valueToFind, fromIndex);
+        }
+    },
+    slice(begin: number, end: number) {
+        this[Self].__realFields();
+        return this[Self].__fields.slice(begin, end).map(toRealField);
+    },
+
+    /// Iteration methods
+    entries() {
+        return this[Self].__realFields().entries();
+    },
+    every(callback: any, thisArg: any) {
+        return this[Self].__realFields().every(callback, thisArg);
+        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+        // If we don't want to support the array parameter, we should use this version instead
+        // return this[Self].__fields.every((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+    },
+    filter(callback: any, thisArg: any) {
+        return this[Self].__realFields().filter(callback, thisArg);
+        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+        // If we don't want to support the array parameter, we should use this version instead
+        // return this[Self].__fields.filter((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+    },
+    find(callback: any, thisArg: any) {
+        return this[Self].__realFields().find(callback, thisArg);
+        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+        // If we don't want to support the array parameter, we should use this version instead
+        // return this[Self].__fields.find((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+    },
+    findIndex(callback: any, thisArg: any) {
+        return this[Self].__realFields().findIndex(callback, thisArg);
+        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+        // If we don't want to support the array parameter, we should use this version instead
+        // return this[Self].__fields.findIndex((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+    },
+    forEach(callback: any, thisArg: any) {
+        return this[Self].__realFields().forEach(callback, thisArg);
+        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+        // If we don't want to support the array parameter, we should use this version instead
+        // return this[Self].__fields.forEach((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+    },
+    map(callback: any, thisArg: any) {
+        return this[Self].__realFields().map(callback, thisArg);
+        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+        // If we don't want to support the array parameter, we should use this version instead
+        // return this[Self].__fields.map((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+    },
+    reduce(callback: any, initialValue: any) {
+        return this[Self].__realFields().reduce(callback, initialValue);
+        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+        // If we don't want to support the array parameter, we should use this version instead
+        // return this[Self].__fields.reduce((acc:any, element:any, index:number, array:any) => callback(acc, toRealField(element), index, array), initialValue);
+    },
+    reduceRight(callback: any, initialValue: any) {
+        return this[Self].__realFields().reduceRight(callback, initialValue);
+        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+        // If we don't want to support the array parameter, we should use this version instead
+        // return this[Self].__fields.reduceRight((acc:any, element:any, index:number, array:any) => callback(acc, toRealField(element), index, array), initialValue);
+    },
+    some(callback: any, thisArg: any) {
+        return this[Self].__realFields().some(callback, thisArg);
+        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
+        // If we don't want to support the array parameter, we should use this version instead
+        // return this[Self].__fields.some((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
+    },
+    values() {
+        return this[Self].__realFields().values();
+    },
+    [Symbol.iterator]() {
+        return this[Self].__realFields().values();
+    }
+};
+
+function toObjectField(field: Field) {
+    return field instanceof RefField ? new ProxyField(field) : field;
+}
+
+function toRealField(field: Field) {
+    return field instanceof ProxyField ? field.value() : field;
+}
+
+function listGetter(target: any, prop: string | number | symbol, receiver: any): any {
+    if (listHandlers.hasOwnProperty(prop)) {
+        return listHandlers[prop];
+    }
+    return getter(target, prop, receiver);
+}
+
+interface ListSpliceUpdate<T> {
+    type: "splice";
+    index: number;
+    added: T[];
+    removedCount: number;
+}
+
+interface ListIndexUpdate<T> {
+    type: "update";
+    index: number;
+    newValue: T;
+}
+
+type ListUpdate<T> = ListSpliceUpdate<T> | ListIndexUpdate<T>;
+
+type StoredType<T extends Field> = T extends RefField ? ProxyField<T> : T;
+
+@Deserializable("list")
+class ListImpl<T extends Field> extends ObjectField {
+    constructor(fields?: T[]) {
+        super();
+        const list = new Proxy<this>(this, {
+            set: setter,
+            get: listGetter,
+            ownKeys: target => Object.keys(target.__fields),
+            getOwnPropertyDescriptor: (target, prop) => {
+                if (prop in target.__fields) {
+                    return {
+                        configurable: true,//TODO Should configurable be true?
+                        enumerable: true,
+                    };
+                }
+                return Reflect.getOwnPropertyDescriptor(target, prop);
+            },
+            deleteProperty: deleteProperty,
+            defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
+        });
+        this[SelfProxy] = list;
+        if (fields) {
+            (list as any).push(...fields);
+        }
+        return list;
+    }
+
+    [key: number]: T | (T extends RefField ? Promise<T> : never);
+
+    // this requests all ProxyFields at the same time to avoid the overhead
+    // of separate network requests and separate updates to the React dom.
+    private __realFields() {
+        const waiting = this.__fields.filter(f => f instanceof ProxyField && f.promisedValue());
+        const promised = waiting.map(f => f instanceof ProxyField ? f.promisedValue() : "");
+        // if we find any ProxyFields that don't have a current value, then
+        // start the server request for all of them
+        if (promised.length) {
+            const promise = DocServer.GetRefFields(promised);
+            // as soon as we get the fields from the server, set all the list values in one
+            // action to generate one React dom update.
+            promise.then(fields => runInAction(() => {
+                waiting.map((w, i) => w instanceof ProxyField && w.setValue(fields[promised[i]]));
+            }));
+            // we also have to mark all lists items with this promise so that any calls to them
+            // will await the batch request.
+            // This counts on the handler for 'promise' in the call above being invoked before the
+            // handler for 'promise' in the lines below.
+            waiting.map((w, i) => {
+                w instanceof ProxyField && w.setPromise(promise.then(fields => fields[promised[i]]));
+            });
+        }
+        return this.__fields.map(toRealField);
+    }
+
+    @serializable(alias("fields", list(autoObject(), { afterDeserialize: afterDocDeserialize })))
+    private get __fields() {
+        return this.___fields;
+    }
+
+    private set __fields(value) {
+        this.___fields = value;
+        for (const key in value) {
+            const field = value[key];
+            if (!(field instanceof ObjectField)) continue;
+            (field as ObjectField)[Parent] = this[Self];
+            (field as ObjectField)[OnUpdate] = updateFunction(this[Self], key, field, this[SelfProxy]);
+        }
+    }
+
+    [Copy]() {
+        const copiedData = this[Self].__fields.map(f => f instanceof ObjectField ? f[Copy]() : f);
+        const deepCopy = new ListImpl<T>(copiedData as any);
+        return deepCopy;
+    }
+
+    // @serializable(alias("fields", list(autoObject())))
+    @observable
+    private ___fields: StoredType<T>[] = [];
+
+    private [Update] = (diff: any) => {
+        // console.log(diff);
+        const update = this[OnUpdate];
+        // update && update(diff);
+        update?.();
+    }
+
+    private [Self] = this;
+    private [SelfProxy]: any;
+
+    [ToScriptString]() {
+        return `new List([${(this as any).map((field: any) => Field.toScriptString(field))}])`;
+    }
+    [ToString]() {
+        return "List";
+    }
+}
+export type List<T extends Field> = ListImpl<T> & (T | (T extends RefField ? Promise<T> : never))[];
+export const List: { new <T extends Field>(fields?: T[]): List<T> } = ListImpl as any;
+
+Scripting.addGlobal("List", List);
\ No newline at end of file
diff --git a/src/fields/ListSpec.ts b/src/fields/ListSpec.ts
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/fields/ObjectField.ts b/src/fields/ObjectField.ts
new file mode 100644
index 000000000..9aa1c9b04
--- /dev/null
+++ b/src/fields/ObjectField.ts
@@ -0,0 +1,20 @@
+import { RefField } from "./RefField";
+import { OnUpdate, Parent, Copy, ToScriptString, ToString } from "./FieldSymbols";
+import { Scripting } from "../client/util/Scripting";
+
+export abstract class ObjectField {
+    protected [OnUpdate](diff?: any) { }
+    private [Parent]?: RefField | ObjectField;
+    abstract [Copy](): ObjectField;
+
+    abstract [ToScriptString](): string;
+    abstract [ToString](): string;
+}
+
+export namespace ObjectField {
+    export function MakeCopy<T extends ObjectField>(field: T) {
+        return field?.[Copy]();
+    }
+}
+
+Scripting.addGlobal(ObjectField);
\ No newline at end of file
diff --git a/src/fields/PresField.ts b/src/fields/PresField.ts
new file mode 100644
index 000000000..f236a04fd
--- /dev/null
+++ b/src/fields/PresField.ts
@@ -0,0 +1,6 @@
+//insert code here
+import { ObjectField } from "./ObjectField";
+
+export abstract class PresField extends ObjectField {
+
+}
\ No newline at end of file
diff --git a/src/fields/Proxy.ts b/src/fields/Proxy.ts
new file mode 100644
index 000000000..555faaad0
--- /dev/null
+++ b/src/fields/Proxy.ts
@@ -0,0 +1,126 @@
+import { Deserializable } from "../client/util/SerializationHelper";
+import { FieldWaiting } from "./Doc";
+import { primitive, serializable } from "serializr";
+import { observable, action, runInAction } from "mobx";
+import { DocServer } from "../client/DocServer";
+import { RefField } from "./RefField";
+import { ObjectField } from "./ObjectField";
+import { Id, Copy, ToScriptString, ToString } from "./FieldSymbols";
+import { scriptingGlobal } from "../client/util/Scripting";
+import { Plugins } from "./util";
+
+@Deserializable("proxy")
+export class ProxyField<T extends RefField> extends ObjectField {
+    constructor();
+    constructor(value: T);
+    constructor(fieldId: string);
+    constructor(value?: T | string) {
+        super();
+        if (typeof value === "string") {
+            this.fieldId = value;
+        } else if (value) {
+            this.cache = value;
+            this.fieldId = value[Id];
+        }
+    }
+
+    [Copy]() {
+        if (this.cache) return new ProxyField<T>(this.cache);
+        return new ProxyField<T>(this.fieldId);
+    }
+
+    [ToScriptString]() {
+        return "invalid";
+    }
+    [ToString]() {
+        return "ProxyField";
+    }
+
+    @serializable(primitive())
+    readonly fieldId: string = "";
+
+    // This getter/setter and nested object thing is 
+    // because mobx doesn't play well with observable proxies
+    @observable.ref
+    private _cache: { readonly field: T | undefined } = { field: undefined };
+    private get cache(): T | undefined {
+        return this._cache.field;
+    }
+    private set cache(field: T | undefined) {
+        this._cache = { field };
+    }
+
+    private failed = false;
+    private promise?: Promise<any>;
+
+    value(): T | undefined | FieldWaiting<T> {
+        if (this.cache) {
+            return this.cache;
+        }
+        if (this.failed) {
+            return undefined;
+        }
+        if (!this.promise) {
+            const cached = DocServer.GetCachedRefField(this.fieldId);
+            if (cached !== undefined) {
+                runInAction(() => this.cache = cached as any);
+                return cached as any;
+            }
+            this.promise = DocServer.GetRefField(this.fieldId).then(action((field: any) => {
+                this.promise = undefined;
+                this.cache = field;
+                if (field === undefined) this.failed = true;
+                return field;
+            }));
+        }
+        return this.promise as any;
+    }
+    promisedValue(): string { return !this.cache && !this.failed && !this.promise ? this.fieldId : ""; }
+    setPromise(promise: any) {
+        this.promise = promise;
+    }
+    @action
+    setValue(field: any) {
+        this.promise = undefined;
+        this.cache = field;
+        if (field === undefined) this.failed = true;
+        return field;
+    }
+}
+
+export namespace ProxyField {
+    let useProxy = true;
+    export function DisableProxyFields() {
+        useProxy = false;
+    }
+
+    export function EnableProxyFields() {
+        useProxy = true;
+    }
+
+    export function WithoutProxy<T>(fn: () => T) {
+        DisableProxyFields();
+        try {
+            return fn();
+        } finally {
+            EnableProxyFields();
+        }
+    }
+
+    export function initPlugin() {
+        Plugins.addGetterPlugin((doc, _, value) => {
+            if (useProxy && value instanceof ProxyField) {
+                return { value: value.value() };
+            }
+        });
+    }
+}
+
+function prefetchValue(proxy: PrefetchProxy<RefField>) {
+    return proxy.value() as any;
+}
+
+@scriptingGlobal
+@Deserializable("prefetch_proxy", prefetchValue)
+export class PrefetchProxy<T extends RefField> extends ProxyField<T> {
+}
diff --git a/src/fields/RefField.ts b/src/fields/RefField.ts
new file mode 100644
index 000000000..b6ef69750
--- /dev/null
+++ b/src/fields/RefField.ts
@@ -0,0 +1,21 @@
+import { serializable, primitive, alias } from "serializr";
+import { Utils } from "../Utils";
+import { Id, HandleUpdate, ToScriptString, ToString } from "./FieldSymbols";
+import { afterDocDeserialize } from "../client/util/SerializationHelper";
+
+export type FieldId = string;
+export abstract class RefField {
+    @serializable(alias("id", primitive({ afterDeserialize: afterDocDeserialize })))
+    private __id: FieldId;
+    readonly [Id]: FieldId;
+
+    constructor(id?: FieldId) {
+        this.__id = id || Utils.GenerateGuid();
+        this[Id] = this.__id;
+    }
+
+    protected [HandleUpdate]?(diff: any): void | Promise<void>;
+
+    abstract [ToScriptString](): string;
+    abstract [ToString](): string;
+}
diff --git a/src/fields/RichTextField.ts b/src/fields/RichTextField.ts
new file mode 100644
index 000000000..5cf0e0cc3
--- /dev/null
+++ b/src/fields/RichTextField.ts
@@ -0,0 +1,41 @@
+import { ObjectField } from "./ObjectField";
+import { serializable } from "serializr";
+import { Deserializable } from "../client/util/SerializationHelper";
+import { Copy, ToScriptString, ToPlainText, ToString } from "./FieldSymbols";
+import { scriptingGlobal } from "../client/util/Scripting";
+
+@scriptingGlobal
+@Deserializable("RichTextField")
+export class RichTextField extends ObjectField {
+    @serializable(true)
+    readonly Data: string;
+
+    @serializable(true)
+    readonly Text: string;
+
+    constructor(data: string, text: string = "") {
+        super();
+        this.Data = data;
+        this.Text = text;
+    }
+
+    Empty() {
+        return !(this.Text || this.Data.toString().includes("dashField"));
+    }
+
+    [Copy]() {
+        return new RichTextField(this.Data, this.Text);
+    }
+
+    [ToScriptString]() {
+        return `new RichTextField("${this.Data}", "${this.Text}")`;
+    }
+    [ToString]() {
+        return this.Text;
+    }
+
+    public static DashField(fieldKey: string) {
+        return new RichTextField(`{"doc":{"type":"doc","content":[{"type":"paragraph","attrs":{"align":null,"color":null,"id":null,"indent":null,"inset":null,"lineSpacing":null,"paddingBottom":null,"paddingTop":null},"content":[{"type":"dashField","attrs":{"fieldKey":"${fieldKey}","docid":""}}]}]},"selection":{"type":"text","anchor":2,"head":2},"storedMarks":[]}`, "");
+    }
+
+}
\ No newline at end of file
diff --git a/src/fields/RichTextUtils.ts b/src/fields/RichTextUtils.ts
new file mode 100644
index 000000000..c475d0d73
--- /dev/null
+++ b/src/fields/RichTextUtils.ts
@@ -0,0 +1,519 @@
+import { AssertionError } from "assert";
+import { docs_v1 } from "googleapis";
+import { Fragment, Mark, Node } from "prosemirror-model";
+import { sinkListItem } from "prosemirror-schema-list";
+import { Utils } from "../Utils";
+import { Docs } from "../client/documents/Documents";
+import { schema } from "../client/views/nodes/formattedText/schema_rts";
+import { GooglePhotos } from "../client/apis/google_docs/GooglePhotosClientUtils";
+import { DocServer } from "../client/DocServer";
+import { Networking } from "../client/Network";
+import { FormattedTextBox } from "../client/views/nodes/formattedText/FormattedTextBox";
+import { Doc, Opt } from "./Doc";
+import { Id } from "./FieldSymbols";
+import { RichTextField } from "./RichTextField";
+import { Cast, StrCast } from "./Types";
+import Color = require('color');
+import { EditorState, TextSelection, Transaction } from "prosemirror-state";
+import { GoogleApiClientUtils } from "../client/apis/google_docs/GoogleApiClientUtils";
+
+export namespace RichTextUtils {
+
+    const delimiter = "\n";
+    const joiner = "";
+
+
+    export const Initialize = (initial?: string) => {
+        const content: any[] = [];
+        const state = {
+            doc: {
+                type: "doc",
+                content,
+            },
+            selection: {
+                type: "text",
+                anchor: 0,
+                head: 0
+            }
+        };
+        if (initial && initial.length) {
+            content.push({
+                type: "paragraph",
+                content: {
+                    type: "text",
+                    text: initial
+                }
+            });
+            state.selection.anchor = state.selection.head = initial.length + 1;
+        }
+        return JSON.stringify(state);
+    };
+
+    export const Synthesize = (plainText: string, oldState?: RichTextField) => {
+        return new RichTextField(ToProsemirrorState(plainText, oldState), plainText);
+    };
+
+    export const ToPlainText = (state: EditorState) => {
+        // Because we're working with plain text, just concatenate all paragraphs
+        const content = state.doc.content;
+        const paragraphs: Node<any>[] = [];
+        content.forEach(node => node.type.name === "paragraph" && paragraphs.push(node));
+
+        // Functions to flatten ProseMirror paragraph objects (and their components) to plain text
+        // Concatentate paragraphs and string the result together
+        const textParagraphs: string[] = paragraphs.map(paragraph => {
+            const text: string[] = [];
+            paragraph.content.forEach(node => node.text && text.push(node.text));
+            return text.join(joiner) + delimiter;
+        });
+        const plainText = textParagraphs.join(joiner);
+        return plainText.substring(0, plainText.length - 1);
+    };
+
+    export const ToProsemirrorState = (plainText: string, oldState?: RichTextField) => {
+        // Remap the text, creating blocks split on newlines
+        const elements = plainText.split(delimiter);
+
+        // Google Docs adds in an extra carriage return automatically, so this counteracts it
+        !elements[elements.length - 1].length && elements.pop();
+
+        // Preserve the current state, but re-write the content to be the blocks
+        const parsed = JSON.parse(oldState ? oldState.Data : Initialize());
+        parsed.doc.content = elements.map(text => {
+            const paragraph: any = { type: "paragraph" };
+            text.length && (paragraph.content = [{ type: "text", marks: [], text }]); // An empty paragraph gets treated as a line break
+            return paragraph;
+        });
+
+        // If the new content is shorter than the previous content and selection is unchanged, may throw an out of bounds exception, so we reset it
+        parsed.selection = { type: "text", anchor: 1, head: 1 };
+
+        // Export the ProseMirror-compatible state object we've just built
+        return JSON.stringify(parsed);
+    };
+
+    export namespace GoogleDocs {
+
+        export const Export = async (state: EditorState): Promise<GoogleApiClientUtils.Docs.Content> => {
+            const nodes: (Node<any> | null)[] = [];
+            const text = ToPlainText(state);
+            state.doc.content.forEach(node => {
+                if (!node.childCount) {
+                    nodes.push(null);
+                } else {
+                    node.content.forEach(child => nodes.push(child));
+                }
+            });
+            const requests = await marksToStyle(nodes);
+            return { text, requests };
+        };
+
+        interface ImageTemplate {
+            width: number;
+            title: string;
+            url: string;
+            agnostic: string;
+        }
+
+        const parseInlineObjects = async (document: docs_v1.Schema$Document): Promise<Map<string, ImageTemplate>> => {
+            const inlineObjectMap = new Map<string, ImageTemplate>();
+            const inlineObjects = document.inlineObjects;
+
+            if (inlineObjects) {
+                const objects = Object.keys(inlineObjects).map(objectId => inlineObjects[objectId]);
+                const mediaItems: MediaItem[] = objects.map(object => {
+                    const embeddedObject = object.inlineObjectProperties!.embeddedObject!;
+                    return { baseUrl: embeddedObject.imageProperties!.contentUri! };
+                });
+
+                const uploads = await Networking.PostToServer("/googlePhotosMediaGet", { mediaItems });
+
+                if (uploads.length !== mediaItems.length) {
+                    throw new AssertionError({ expected: mediaItems.length, actual: uploads.length, message: "Error with internally uploading inlineObjects!" });
+                }
+
+                for (let i = 0; i < objects.length; i++) {
+                    const object = objects[i];
+                    const { accessPaths } = uploads[i];
+                    const { agnostic, _m } = accessPaths;
+                    const embeddedObject = object.inlineObjectProperties!.embeddedObject!;
+                    const size = embeddedObject.size!;
+                    const width = size.width!.magnitude!;
+
+                    inlineObjectMap.set(object.objectId!, {
+                        title: embeddedObject.title || `Imported Image from ${document.title}`,
+                        width,
+                        url: Utils.prepend(_m.client),
+                        agnostic: Utils.prepend(agnostic.client)
+                    });
+                }
+            }
+            return inlineObjectMap;
+        };
+
+        type BulletPosition = { value: number, sinks: number };
+
+        interface MediaItem {
+            baseUrl: string;
+        }
+
+        export const Import = async (documentId: GoogleApiClientUtils.Docs.DocumentId, textNote: Doc): Promise<Opt<GoogleApiClientUtils.Docs.ImportResult>> => {
+            const document = await GoogleApiClientUtils.Docs.retrieve({ documentId });
+            if (!document) {
+                return undefined;
+            }
+            const inlineObjectMap = await parseInlineObjects(document);
+            const title = document.title!;
+            const { text, paragraphs } = GoogleApiClientUtils.Docs.Utils.extractText(document);
+            let state = FormattedTextBox.blankState();
+            const structured = parseLists(paragraphs);
+
+            let position = 3;
+            const lists: ListGroup[] = [];
+            const indentMap = new Map<ListGroup, BulletPosition[]>();
+            let globalOffset = 0;
+            const nodes: Node<any>[] = [];
+            for (const element of structured) {
+                if (Array.isArray(element)) {
+                    lists.push(element);
+                    const positions: BulletPosition[] = [];
+                    const items = element.map(paragraph => {
+                        const item = listItem(state.schema, paragraph.contents);
+                        const sinks = paragraph.bullet!;
+                        positions.push({
+                            value: position + globalOffset,
+                            sinks
+                        });
+                        position += item.nodeSize;
+                        globalOffset += 2 * sinks;
+                        return item;
+                    });
+                    indentMap.set(element, positions);
+                    nodes.push(list(state.schema, items));
+                } else {
+                    if (element.contents.some(child => "inlineObjectId" in child)) {
+                        const group = element.contents;
+                        group.forEach((child, i) => {
+                            let node: Opt<Node<any>>;
+                            if ("inlineObjectId" in child) {
+                                node = imageNode(state.schema, inlineObjectMap.get(child.inlineObjectId!)!, textNote);
+                            } else if ("content" in child && (i !== group.length - 1 || child.content!.removeTrailingNewlines().length)) {
+                                node = paragraphNode(state.schema, [child]);
+                            }
+                            if (node) {
+                                position += node.nodeSize;
+                                nodes.push(node);
+                            }
+                        });
+                    } else {
+                        const paragraph = paragraphNode(state.schema, element.contents);
+                        nodes.push(paragraph);
+                        position += paragraph.nodeSize;
+                    }
+                }
+            }
+            state = state.apply(state.tr.replaceWith(0, 2, nodes));
+
+            const sink = sinkListItem(state.schema.nodes.list_item);
+            const dispatcher = (tr: Transaction) => state = state.apply(tr);
+            for (const list of lists) {
+                for (const pos of indentMap.get(list)!) {
+                    const resolved = state.doc.resolve(pos.value);
+                    state = state.apply(state.tr.setSelection(new TextSelection(resolved)));
+                    for (let i = 0; i < pos.sinks; i++) {
+                        sink(state, dispatcher);
+                    }
+                }
+            }
+
+            return { title, text, state };
+        };
+
+        type Paragraph = GoogleApiClientUtils.Docs.Utils.DeconstructedParagraph;
+        type ListGroup = Paragraph[];
+        type PreparedParagraphs = (ListGroup | Paragraph)[];
+
+        const parseLists = (paragraphs: ListGroup) => {
+            const groups: PreparedParagraphs = [];
+            let group: ListGroup = [];
+            for (const paragraph of paragraphs) {
+                if (paragraph.bullet !== undefined) {
+                    group.push(paragraph);
+                } else {
+                    if (group.length) {
+                        groups.push(group);
+                        group = [];
+                    }
+                    groups.push(paragraph);
+                }
+            }
+            group.length && groups.push(group);
+            return groups;
+        };
+
+        const listItem = (schema: any, runs: docs_v1.Schema$TextRun[]): Node => {
+            return schema.node("list_item", null, paragraphNode(schema, runs));
+        };
+
+        const list = (schema: any, items: Node[]): Node => {
+            return schema.node("bullet_list", null, items);
+        };
+
+        const paragraphNode = (schema: any, runs: docs_v1.Schema$TextRun[]): Node => {
+            const children = runs.map(run => textNode(schema, run)).filter(child => child !== undefined);
+            const fragment = children.length ? Fragment.from(children) : undefined;
+            return schema.node("paragraph", null, fragment);
+        };
+
+        const imageNode = (schema: any, image: ImageTemplate, textNote: Doc) => {
+            const { url: src, width, agnostic } = image;
+            let docid: string;
+            const guid = Utils.GenerateDeterministicGuid(agnostic);
+            const backingDocId = StrCast(textNote[guid]);
+            if (!backingDocId) {
+                const backingDoc = Docs.Create.ImageDocument(agnostic, { _width: 300, _height: 300 });
+                Doc.makeCustomViewClicked(backingDoc, Docs.Create.FreeformDocument);
+                docid = backingDoc[Id];
+                textNote[guid] = docid;
+            } else {
+                docid = backingDocId;
+            }
+            return schema.node("image", { src, agnostic, width, docid, float: null, location: "onRight" });
+        };
+
+        const textNode = (schema: any, run: docs_v1.Schema$TextRun) => {
+            const text = run.content!.removeTrailingNewlines();
+            return text.length ? schema.text(text, styleToMarks(schema, run.textStyle)) : undefined;
+        };
+
+        const StyleToMark = new Map<keyof docs_v1.Schema$TextStyle, keyof typeof schema.marks>([
+            ["bold", "strong"],
+            ["italic", "em"],
+            ["foregroundColor", "pFontColor"],
+            ["fontSize", "pFontSize"]
+        ]);
+
+        const styleToMarks = (schema: any, textStyle?: docs_v1.Schema$TextStyle) => {
+            if (!textStyle) {
+                return undefined;
+            }
+            const marks: Mark[] = [];
+            Object.keys(textStyle).forEach(key => {
+                let value: any;
+                const targeted = key as keyof docs_v1.Schema$TextStyle;
+                if (value = textStyle[targeted]) {
+                    const attributes: any = {};
+                    let converted = StyleToMark.get(targeted) || targeted;
+
+                    value.url && (attributes.href = value.url);
+                    if (value.color) {
+                        const object = value.color.rgbColor;
+                        attributes.color = Color.rgb(["red", "green", "blue"].map(color => object[color] * 255 || 0)).hex();
+                    }
+                    if (value.magnitude) {
+                        attributes.fontSize = value.magnitude;
+                    }
+
+                    if (converted === "weightedFontFamily") {
+                        converted = ImportFontFamilyMapping.get(value.fontFamily) || "timesNewRoman";
+                    }
+
+                    const mapped = schema.marks[converted];
+                    if (!mapped) {
+                        alert(`No mapping found for ${converted}!`);
+                        return;
+                    }
+
+                    const mark = schema.mark(mapped, attributes);
+                    mark && marks.push(mark);
+                }
+            });
+            return marks;
+        };
+
+        const MarkToStyle = new Map<keyof typeof schema.marks, keyof docs_v1.Schema$TextStyle>([
+            ["strong", "bold"],
+            ["em", "italic"],
+            ["pFontColor", "foregroundColor"],
+            ["pFontSize", "fontSize"],
+            ["timesNewRoman", "weightedFontFamily"],
+            ["georgia", "weightedFontFamily"],
+            ["comicSans", "weightedFontFamily"],
+            ["tahoma", "weightedFontFamily"],
+            ["impact", "weightedFontFamily"]
+        ]);
+
+        const ExportFontFamilyMapping = new Map<string, string>([
+            ["timesNewRoman", "Times New Roman"],
+            ["arial", "Arial"],
+            ["georgia", "Georgia"],
+            ["comicSans", "Comic Sans MS"],
+            ["tahoma", "Tahoma"],
+            ["impact", "Impact"]
+        ]);
+
+        const ImportFontFamilyMapping = new Map<string, string>([
+            ["Times New Roman", "timesNewRoman"],
+            ["Arial", "arial"],
+            ["Georgia", "georgia"],
+            ["Comic Sans MS", "comicSans"],
+            ["Tahoma", "tahoma"],
+            ["Impact", "impact"]
+        ]);
+
+        const ignored = ["user_mark"];
+
+        const marksToStyle = async (nodes: (Node<any> | null)[]): Promise<docs_v1.Schema$Request[]> => {
+            const requests: docs_v1.Schema$Request[] = [];
+            let position = 1;
+            for (const node of nodes) {
+                if (node === null) {
+                    position += 2;
+                    continue;
+                }
+                const { marks, attrs, nodeSize } = node;
+                const textStyle: docs_v1.Schema$TextStyle = {};
+                const information: LinkInformation = {
+                    startIndex: position,
+                    endIndex: position + nodeSize,
+                    textStyle
+                };
+                let mark: Mark<any>;
+                const markMap = BuildMarkMap(marks);
+                for (const markName of Object.keys(schema.marks)) {
+                    if (ignored.includes(markName) || !(mark = markMap[markName])) {
+                        continue;
+                    }
+                    let converted = MarkToStyle.get(markName) || markName as keyof docs_v1.Schema$TextStyle;
+                    let value: any = true;
+                    if (!converted) {
+                        continue;
+                    }
+                    const { attrs } = mark;
+                    switch (converted) {
+                        case "link":
+                            let url = attrs.href;
+                            const delimiter = "/doc/";
+                            const alreadyShared = "?sharing=true";
+                            if (new RegExp(window.location.origin + delimiter).test(url) && !url.endsWith(alreadyShared)) {
+                                const linkDoc = await DocServer.GetRefField(url.split(delimiter)[1]);
+                                if (linkDoc instanceof Doc) {
+                                    let exported = (await Cast(linkDoc.anchor2, Doc))!;
+                                    if (!exported.customLayout) {
+                                        exported = Doc.MakeAlias(exported);
+                                        Doc.makeCustomViewClicked(exported, Docs.Create.FreeformDocument);
+                                        linkDoc.anchor2 = exported;
+                                    }
+                                    url = Utils.shareUrl(exported[Id]);
+                                }
+                            }
+                            value = { url };
+                            textStyle.foregroundColor = fromRgb.blue;
+                            textStyle.bold = true;
+                            break;
+                        case "fontSize":
+                            value = { magnitude: attrs.fontSize, unit: "PT" };
+                            break;
+                        case "foregroundColor":
+                            value = fromHex(attrs.color);
+                            break;
+                        case "weightedFontFamily":
+                            value = { fontFamily: ExportFontFamilyMapping.get(markName) };
+                    }
+                    let matches: RegExpExecArray | null;
+                    if ((matches = /p(\d+)/g.exec(markName)) !== null) {
+                        converted = "fontSize";
+                        value = { magnitude: parseInt(matches[1].replace("px", "")), unit: "PT" };
+                    }
+                    textStyle[converted] = value;
+                }
+                if (Object.keys(textStyle).length) {
+                    requests.push(EncodeStyleUpdate(information));
+                }
+                if (node.type.name === "image") {
+                    const width = attrs.width;
+                    requests.push(await EncodeImage({
+                        startIndex: position + nodeSize - 1,
+                        uri: attrs.agnostic,
+                        width: Number(typeof width === "string" ? width.replace("px", "") : width)
+                    }));
+                }
+                position += nodeSize;
+            }
+            return requests;
+        };
+
+        const BuildMarkMap = (marks: Mark<any>[]) => {
+            const markMap: { [type: string]: Mark<any> } = {};
+            marks.forEach(mark => markMap[mark.type.name] = mark);
+            return markMap;
+        };
+
+        interface LinkInformation {
+            startIndex: number;
+            endIndex: number;
+            textStyle: docs_v1.Schema$TextStyle;
+        }
+
+        interface ImageInformation {
+            startIndex: number;
+            width: number;
+            uri: string;
+        }
+
+        namespace fromRgb {
+
+            export const convert = (red: number, green: number, blue: number): docs_v1.Schema$OptionalColor => {
+                return {
+                    color: {
+                        rgbColor: {
+                            red: red / 255,
+                            green: green / 255,
+                            blue: blue / 255
+                        }
+                    }
+                };
+            };
+
+            export const red = convert(255, 0, 0);
+            export const green = convert(0, 255, 0);
+            export const blue = convert(0, 0, 255);
+
+        }
+
+        const fromHex = (color: string): docs_v1.Schema$OptionalColor => {
+            const c = Color(color);
+            return fromRgb.convert(c.red(), c.green(), c.blue());
+        };
+
+        const EncodeStyleUpdate = (information: LinkInformation): docs_v1.Schema$Request => {
+            const { startIndex, endIndex, textStyle } = information;
+            return {
+                updateTextStyle: {
+                    fields: "*",
+                    range: { startIndex, endIndex },
+                    textStyle
+                } as docs_v1.Schema$UpdateTextStyleRequest
+            };
+        };
+
+        const EncodeImage = async ({ uri, width, startIndex }: ImageInformation) => {
+            if (!uri) {
+                return {};
+            }
+            const source = [Docs.Create.ImageDocument(uri)];
+            const baseUrls = await GooglePhotos.Transactions.UploadThenFetch(source);
+            if (baseUrls) {
+                return {
+                    insertInlineImage: {
+                        uri: baseUrls[0],
+                        objectSize: { width: { magnitude: width, unit: "PT" } },
+                        location: { index: startIndex }
+                    }
+                };
+            }
+            return {};
+        };
+    }
+
+}
\ No newline at end of file
diff --git a/src/fields/Schema.ts b/src/fields/Schema.ts
new file mode 100644
index 000000000..72bce283d
--- /dev/null
+++ b/src/fields/Schema.ts
@@ -0,0 +1,120 @@
+import { Interface, ToInterface, Cast, ToConstructor, HasTail, Head, Tail, ListSpec, ToType, DefaultFieldConstructor } from "./Types";
+import { Doc, Field } from "./Doc";
+import { ObjectField } from "./ObjectField";
+import { RefField } from "./RefField";
+import { SelfProxy } from "./FieldSymbols";
+
+type AllToInterface<T extends Interface[]> = {
+    1: ToInterface<Head<T>> & AllToInterface<Tail<T>>,
+    0: ToInterface<Head<T>>
+}[HasTail<T> extends true ? 1 : 0];
+
+export const emptySchema = createSchema({});
+export const Document = makeInterface(emptySchema);
+export type Document = makeInterface<[typeof emptySchema]>;
+
+export interface InterfaceFunc<T extends Interface[]> {
+    (docs: Doc[]): makeInterface<T>[];
+    (): makeInterface<T>;
+    (doc: Doc): makeInterface<T>;
+}
+
+export type makeInterface<T extends Interface[]> = AllToInterface<T> & Doc & { proto: Doc | undefined };
+// export function makeInterface<T extends Interface[], U extends Doc>(schemas: T): (doc: U) => All<T, U>;
+// export function makeInterface<T extends Interface, U extends Doc>(schema: T): (doc: U) => makeInterface<T, U>; 
+export function makeInterface<T extends Interface[]>(...schemas: T): InterfaceFunc<T> {
+    const schema: Interface = {};
+    for (const s of schemas) {
+        for (const key in s) {
+            schema[key] = s[key];
+        }
+    }
+    const proto = new Proxy({}, {
+        get(target: any, prop, receiver) {
+            const field = receiver.doc[prop];
+            if (prop in schema) {
+                const desc = prop === "proto" ? Doc : (schema as any)[prop]; // bcz: proto doesn't appear in schemas ... maybe it should?
+                if (typeof desc === "object" && "defaultVal" in desc && "type" in desc) {//defaultSpec
+                    return Cast(field, desc.type, desc.defaultVal);
+                } else if (typeof desc === "function" && !ObjectField.isPrototypeOf(desc) && !RefField.isPrototypeOf(desc)) {
+                    const doc = Cast(field, Doc);
+                    if (doc === undefined) {
+                        return undefined;
+                    } else if (doc instanceof Doc) {
+                        return desc(doc);
+                    } else {
+                        return doc.then(doc => doc && desc(doc));
+                    }
+                } else {
+                    return Cast(field, desc);
+                }
+            }
+            return field;
+        },
+        set(target: any, prop, value, receiver) {
+            receiver.doc[prop] = value;
+            return true;
+        }
+    });
+    const fn = (doc: Doc) => {
+        doc = doc[SelfProxy];
+        // if (!(doc instanceof Doc)) {
+        //     throw new Error("Currently wrapping a schema in another schema isn't supported");
+        // }
+        const obj = Object.create(proto, { doc: { value: doc, writable: false } });
+        return obj;
+    };
+    return function (doc?: Doc | Doc[]) {
+        doc = doc || new Doc;
+        if (doc instanceof Doc) {
+            return fn(doc);
+        } else {
+            return doc.map(fn);
+        }
+    };
+}
+
+export type makeStrictInterface<T extends Interface> = Partial<ToInterface<T>>;
+export function makeStrictInterface<T extends Interface>(schema: T): (doc: Doc) => makeStrictInterface<T> {
+    const proto = {};
+    for (const key in schema) {
+        const type = schema[key];
+        Object.defineProperty(proto, key, {
+            get() {
+                return Cast(this.__doc[key], type as any);
+            },
+            set(value) {
+                value = Cast(value, type as any);
+                if (value !== undefined) {
+                    this.__doc[key] = value;
+                    return;
+                }
+                throw new TypeError("Expected type " + type);
+            }
+        });
+    }
+    return function (doc: any) {
+        if (!(doc instanceof Doc)) {
+            throw new Error("Currently wrapping a schema in another schema isn't supported");
+        }
+        const obj = Object.create(proto);
+        obj.__doc = doc;
+        return obj;
+    };
+}
+
+export function createSchema<T extends Interface>(schema: T): T & { proto: ToConstructor<Doc> } {
+    (schema as any).proto = Doc;
+    return schema as any;
+}
+
+export function listSpec<U extends ToConstructor<Field>>(type: U): ListSpec<ToType<U>> {
+    return { List: type as any };//TODO Types
+}
+
+export function defaultSpec<T extends ToConstructor<Field>>(type: T, defaultVal: ToType<T>): DefaultFieldConstructor<ToType<T>> {
+    return {
+        type: type as any,
+        defaultVal
+    };
+}
\ No newline at end of file
diff --git a/src/fields/SchemaHeaderField.ts b/src/fields/SchemaHeaderField.ts
new file mode 100644
index 000000000..07c90f5a2
--- /dev/null
+++ b/src/fields/SchemaHeaderField.ts
@@ -0,0 +1,122 @@
+import { Deserializable } from "../client/util/SerializationHelper";
+import { serializable, primitive } from "serializr";
+import { ObjectField } from "./ObjectField";
+import { Copy, ToScriptString, ToString, OnUpdate } from "./FieldSymbols";
+import { scriptingGlobal } from "../client/util/Scripting";
+import { ColumnType } from "../client/views/collections/CollectionSchemaView";
+
+export const PastelSchemaPalette = new Map<string, string>([
+    // ["pink1", "#FFB4E8"],
+    ["pink2", "#ff9cee"],
+    ["pink3", "#ffccf9"],
+    ["pink4", "#fcc2ff"],
+    ["pink5", "#f6a6ff"],
+    ["purple1", "#b28dff"],
+    ["purple2", "#c5a3ff"],
+    ["purple3", "#d5aaff"],
+    ["purple4", "#ecd4ff"],
+    // ["purple5", "#fb34ff"],
+    ["purple6", "#dcd3ff"],
+    ["purple7", "#a79aff"],
+    ["purple8", "#b5b9ff"],
+    ["purple9", "#97a2ff"],
+    ["bluegreen1", "#afcbff"],
+    ["bluegreen2", "#aff8db"],
+    ["bluegreen3", "#c4faf8"],
+    ["bluegreen4", "#85e3ff"],
+    ["bluegreen5", "#ace7ff"],
+    // ["bluegreen6", "#6eb5ff"],
+    ["bluegreen7", "#bffcc6"],
+    ["bluegreen8", "#dbffd6"],
+    ["yellow1", "#f3ffe3"],
+    ["yellow2", "#e7ffac"],
+    ["yellow3", "#ffffd1"],
+    ["yellow4", "#fff5ba"],
+    // ["red1", "#ffc9de"],
+    ["red2", "#ffabab"],
+    ["red3", "#ffbebc"],
+    ["red4", "#ffcbc1"],
+    ["orange1", "#ffd5b3"],
+]);
+
+export const RandomPastel = () => Array.from(PastelSchemaPalette.values())[Math.floor(Math.random() * PastelSchemaPalette.size)];
+
+export const DarkPastelSchemaPalette = new Map<string, string>([
+    ["pink2", "#c932b0"],
+    ["purple4", "#913ad6"],
+    ["bluegreen1", "#3978ed"],
+    ["bluegreen7", "#2adb3e"],
+    ["bluegreen5", "#21b0eb"],
+    ["yellow4", "#edcc0c"],
+    ["red2", "#eb3636"],
+    ["orange1", "#f2740f"],
+]);
+
+@scriptingGlobal
+@Deserializable("schemaheader")
+export class SchemaHeaderField extends ObjectField {
+    @serializable(primitive())
+    heading: string;
+    @serializable(primitive())
+    color: string;
+    @serializable(primitive())
+    type: number;
+    @serializable(primitive())
+    width: number;
+    @serializable(primitive())
+    collapsed: boolean | undefined;
+    @serializable(primitive())
+    desc: boolean | undefined; // boolean determines sort order, undefined when no sort
+
+    constructor(heading: string = "", color: string = RandomPastel(), type?: ColumnType, width?: number, desc?: boolean, collapsed?: boolean) {
+        super();
+
+        this.heading = heading;
+        this.color = color;
+        this.type = type ? type : 0;
+        this.width = width ? width : -1;
+        this.desc = desc;
+        this.collapsed = collapsed;
+    }
+
+    setHeading(heading: string) {
+        this.heading = heading;
+        this[OnUpdate]();
+    }
+
+    setColor(color: string) {
+        this.color = color;
+        this[OnUpdate]();
+    }
+
+    setType(type: ColumnType) {
+        this.type = type;
+        this[OnUpdate]();
+    }
+
+    setWidth(width: number) {
+        this.width = width;
+        this[OnUpdate]();
+    }
+
+    setDesc(desc: boolean | undefined) {
+        this.desc = desc;
+        this[OnUpdate]();
+    }
+
+    setCollapsed(collapsed: boolean | undefined) {
+        this.collapsed = collapsed;
+        this[OnUpdate]();
+    }
+
+    [Copy]() {
+        return new SchemaHeaderField(this.heading, this.color, this.type);
+    }
+
+    [ToScriptString]() {
+        return `invalid`;
+    }
+    [ToString]() {
+        return `SchemaHeaderField`;
+    }
+}
\ No newline at end of file
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
new file mode 100644
index 000000000..f05f431ac
--- /dev/null
+++ b/src/fields/ScriptField.ts
@@ -0,0 +1,193 @@
+import { ObjectField } from "./ObjectField";
+import { CompiledScript, CompileScript, scriptingGlobal, ScriptOptions, CompileError, CompileResult } from "../client/util/Scripting";
+import { Copy, ToScriptString, ToString, Parent, SelfProxy } from "./FieldSymbols";
+import { serializable, createSimpleSchema, map, primitive, object, deserialize, PropSchema, custom, SKIP } from "serializr";
+import { Deserializable, autoObject } from "../client/util/SerializationHelper";
+import { Doc, Field } from "./Doc";
+import { Plugins, setter } from "./util";
+import { computedFn } from "mobx-utils";
+import { ProxyField } from "./Proxy";
+import { Cast } from "./Types";
+
+function optional(propSchema: PropSchema) {
+    return custom(value => {
+        if (value !== undefined) {
+            return propSchema.serializer(value);
+        }
+        return SKIP;
+    }, (jsonValue: any, context: any, oldValue: any, callback: (err: any, result: any) => void) => {
+        if (jsonValue !== undefined) {
+            return propSchema.deserializer(jsonValue, callback, context, oldValue);
+        }
+        return SKIP;
+    });
+}
+
+const optionsSchema = createSimpleSchema({
+    requiredType: true,
+    addReturn: true,
+    typecheck: true,
+    editable: true,
+    readonly: true,
+    params: optional(map(primitive()))
+});
+
+const scriptSchema = createSimpleSchema({
+    options: object(optionsSchema),
+    originalScript: true
+});
+
+async function deserializeScript(script: ScriptField) {
+    const captures: ProxyField<Doc> = (script as any).captures;
+    if (captures) {
+        const doc = (await captures.value())!;
+        const captured: any = {};
+        const keys = Object.keys(doc);
+        const vals = await Promise.all(keys.map(key => doc[key]) as any);
+        keys.forEach((key, i) => captured[key] = vals[i]);
+        (script.script.options as any).capturedVariables = captured;
+    }
+    const comp = CompileScript(script.script.originalScript, script.script.options);
+    if (!comp.compiled) {
+        throw new Error("Couldn't compile loaded script");
+    }
+    (script as any).script = comp;
+}
+
+@scriptingGlobal
+@Deserializable("script", deserializeScript)
+export class ScriptField extends ObjectField {
+    @serializable(object(scriptSchema))
+    readonly script: CompiledScript;
+    @serializable(object(scriptSchema))
+    readonly setterscript: CompiledScript | undefined;
+
+    @serializable(autoObject())
+    private captures?: ProxyField<Doc>;
+
+    constructor(script: CompiledScript, setterscript?: CompileResult) {
+        super();
+
+        if (script?.options.capturedVariables) {
+            const doc = Doc.assign(new Doc, script.options.capturedVariables);
+            this.captures = new ProxyField(doc);
+        }
+        this.setterscript = setterscript?.compiled ? setterscript : undefined;
+        this.script = script;
+    }
+
+    //     init(callback: (res: Field) => any) {
+    //         const options = this.options!;
+    //         const keys = Object.keys(options.options.capturedIds);
+    //         Server.GetFields(keys).then(fields => {
+    //             let captured: { [name: string]: Field } = {};
+    //             keys.forEach(key => captured[options.options.capturedIds[key]] = fields[key]);
+    //             const opts: ScriptOptions = {
+    //                 addReturn: options.options.addReturn,
+    //                 params: options.options.params,
+    //                 requiredType: options.options.requiredType,
+    //                 capturedVariables: captured
+    //             };
+    //             const script = CompileScript(options.script, opts);
+    //             if (!script.compiled) {
+    //                 throw new Error("Can't compile script");
+    //             }
+    //             this._script = script;
+    //             callback(this);
+    //         });
+    //     }
+
+    [Copy](): ObjectField {
+        return new ScriptField(this.script);
+    }
+    toString() {
+        return `${this.script.originalScript}`;
+    }
+
+    [ToScriptString]() {
+        return "script field";
+    }
+    [ToString]() {
+        return this.script.originalScript;
+    }
+    public static CompileScript(script: string, params: object = {}, addReturn = false, capturedVariables?: { [name: string]: Field }) {
+        const compiled = CompileScript(script, {
+            params: { this: Doc.name, self: Doc.name, _last_: "any", ...params },
+            typecheck: false,
+            editable: true,
+            addReturn: addReturn,
+            capturedVariables
+        });
+        return compiled;
+    }
+    public static MakeFunction(script: string, params: object = {}, capturedVariables?: { [name: string]: Field }) {
+        const compiled = ScriptField.CompileScript(script, params, true, capturedVariables);
+        return compiled.compiled ? new ScriptField(compiled) : undefined;
+    }
+
+    public static MakeScript(script: string, params: object = {}, capturedVariables?: { [name: string]: Field }) {
+        const compiled = ScriptField.CompileScript(script, params, false, capturedVariables);
+        return compiled.compiled ? new ScriptField(compiled) : undefined;
+    }
+}
+
+@scriptingGlobal
+@Deserializable("computed", deserializeScript)
+export class ComputedField extends ScriptField {
+    _lastComputedResult: any;
+    //TODO maybe add an observable cache based on what is passed in for doc, considering there shouldn't really be that many possible values for doc
+    value = computedFn((doc: Doc) => this._valueOutsideReaction(doc));
+    _valueOutsideReaction = (doc: Doc) => this._lastComputedResult = this.script.run({ this: doc, self: Cast(doc.rootDocument, Doc, null) || doc, _last_: this._lastComputedResult }, console.log).result;
+
+
+    constructor(script: CompiledScript, setterscript?: CompiledScript) {
+        super(script,
+            !setterscript && script?.originalScript.includes("self.timecode") ?
+                ScriptField.CompileScript("self['x' + self.timecode] = value", { value: "any" }, true) : setterscript);
+    }
+
+    public static MakeScript(script: string, params: object = {}) {
+        const compiled = ScriptField.CompileScript(script, params, false);
+        return compiled.compiled ? new ComputedField(compiled) : undefined;
+    }
+    public static MakeFunction(script: string, params: object = {}, capturedVariables?: { [name: string]: Field }, setterScript?: string) {
+        const compiled = ScriptField.CompileScript(script, params, true, capturedVariables);
+        const setCompiled = setterScript ? ScriptField.CompileScript(setterScript, params, true, capturedVariables) : undefined;
+        return compiled.compiled ? new ComputedField(compiled, setCompiled?.compiled ? setCompiled : undefined) : undefined;
+    }
+    public static MakeInterpolated(fieldKey: string, interpolatorKey: string) {
+        const getField = ScriptField.CompileScript(`(self['${fieldKey}-indexed'])[self.${interpolatorKey}]`, {}, true, {});
+        const setField = ScriptField.CompileScript(`(self['${fieldKey}-indexed'])[self.${interpolatorKey}] = value`, { value: "any" }, true, {});
+        return getField.compiled ? new ComputedField(getField, setField?.compiled ? setField : undefined) : undefined;
+    }
+}
+
+export namespace ComputedField {
+    let useComputed = true;
+    export function DisableComputedFields() {
+        useComputed = false;
+    }
+
+    export function EnableComputedFields() {
+        useComputed = true;
+    }
+
+    export const undefined = "__undefined";
+
+    export function WithoutComputed<T>(fn: () => T) {
+        DisableComputedFields();
+        try {
+            return fn();
+        } finally {
+            EnableComputedFields();
+        }
+    }
+
+    export function initPlugin() {
+        Plugins.addGetterPlugin((doc, _, value) => {
+            if (useComputed && value instanceof ComputedField) {
+                return { value: value._valueOutsideReaction(doc), shouldReturn: true };
+            }
+        });
+    }
+}
\ No newline at end of file
diff --git a/src/fields/Types.ts b/src/fields/Types.ts
new file mode 100644
index 000000000..3d784448d
--- /dev/null
+++ b/src/fields/Types.ts
@@ -0,0 +1,108 @@
+import { Field, Opt, FieldResult, Doc } from "./Doc";
+import { List } from "./List";
+import { RefField } from "./RefField";
+import { DateField } from "./DateField";
+import { ScriptField } from "./ScriptField";
+
+export type ToType<T extends InterfaceValue> =
+    T extends "string" ? string :
+    T extends "number" ? number :
+    T extends "boolean" ? boolean :
+    T extends ListSpec<infer U> ? List<U> :
+    // T extends { new(...args: any[]): infer R } ? (R | Promise<R>) : never;
+    T extends DefaultFieldConstructor<infer _U> ? never :
+    T extends { new(...args: any[]): List<Field> } ? never :
+    T extends { new(...args: any[]): infer R } ? R :
+    T extends (doc?: Doc) => infer R ? R : never;
+
+export type ToConstructor<T extends Field> =
+    T extends string ? "string" :
+    T extends number ? "number" :
+    T extends boolean ? "boolean" :
+    T extends List<infer U> ? ListSpec<U> :
+    new (...args: any[]) => T;
+
+export type ToInterface<T extends Interface> = {
+    [P in Exclude<keyof T, "proto">]: T[P] extends DefaultFieldConstructor<infer F> ? Exclude<FieldResult<F>, undefined> : FieldResult<ToType<T[P]>>;
+};
+
+// type ListSpec<T extends Field[]> = { List: ToContructor<Head<T>> | ListSpec<Tail<T>> };
+export type ListSpec<T extends Field> = { List: ToConstructor<T> };
+
+export type DefaultFieldConstructor<T extends Field> = {
+    type: ToConstructor<T>,
+    defaultVal: T
+};
+
+// type ListType<U extends Field[]> = { 0: List<ListType<Tail<U>>>, 1: ToType<Head<U>> }[HasTail<U> extends true ? 0 : 1];
+
+export type Head<T extends any[]> = T extends [any, ...any[]] ? T[0] : never;
+export type Tail<T extends any[]> =
+    ((...t: T) => any) extends ((_: any, ...tail: infer TT) => any) ? TT : [];
+export type HasTail<T extends any[]> = T extends ([] | [any]) ? false : true;
+
+export type InterfaceValue = ToConstructor<Field> | ListSpec<Field> | DefaultFieldConstructor<Field> | ((doc?: Doc) => any);
+//TODO Allow you to optionally specify default values for schemas, which should then make that field not be partial
+export interface Interface {
+    [key: string]: InterfaceValue;
+    // [key: string]: ToConstructor<Field> | ListSpec<Field[]>;
+}
+export type WithoutRefField<T extends Field> = T extends RefField ? never : T;
+
+export type CastCtor = ToConstructor<Field> | ListSpec<Field>;
+
+export function Cast<T extends CastCtor>(field: FieldResult, ctor: T): FieldResult<ToType<T>>;
+export function Cast<T extends CastCtor>(field: FieldResult, ctor: T, defaultVal: WithoutList<WithoutRefField<ToType<T>>> | null): WithoutList<ToType<T>>;
+export function Cast<T extends CastCtor>(field: FieldResult, ctor: T, defaultVal?: ToType<T> | null): FieldResult<ToType<T>> | undefined {
+    if (field instanceof Promise) {
+        return defaultVal === undefined ? field.then(f => Cast(f, ctor) as any) as any : defaultVal === null ? undefined : defaultVal;
+    }
+    if (field !== undefined && !(field instanceof Promise)) {
+        if (typeof ctor === "string") {
+            if (typeof field === ctor) {
+                return field as ToType<T>;
+            }
+        } else if (typeof ctor === "object") {
+            if (field instanceof List) {
+                return field as any;
+            }
+        } else if (field instanceof (ctor as any)) {
+            return field as ToType<T>;
+        }
+    }
+    return defaultVal === null ? undefined : defaultVal;
+}
+
+export function NumCast(field: FieldResult, defaultVal: number | null = 0) {
+    return Cast(field, "number", defaultVal);
+}
+
+export function StrCast(field: FieldResult, defaultVal: string | null = "") {
+    return Cast(field, "string", defaultVal);
+}
+
+export function BoolCast(field: FieldResult, defaultVal: boolean | null = false) {
+    return Cast(field, "boolean", defaultVal);
+}
+export function DateCast(field: FieldResult) {
+    return Cast(field, DateField, null);
+}
+
+export function ScriptCast(field: FieldResult, defaultVal: ScriptField | null = null) {
+    return Cast(field, ScriptField, defaultVal);
+}
+
+type WithoutList<T extends Field> = T extends List<infer R> ? (R extends RefField ? (R | Promise<R>)[] : R[]) : T;
+
+export function FieldValue<T extends Field, U extends WithoutList<T>>(field: FieldResult<T>, defaultValue: U): WithoutList<T>;
+export function FieldValue<T extends Field>(field: FieldResult<T>): Opt<T>;
+export function FieldValue<T extends Field>(field: FieldResult<T>, defaultValue?: T): Opt<T> {
+    return (field instanceof Promise || field === undefined) ? defaultValue : field;
+}
+
+export interface PromiseLike<T> {
+    then(callback: (field: Opt<T>) => void): void;
+}
+export function PromiseValue<T extends Field>(field: FieldResult<T>): PromiseLike<Opt<T>> {
+    return field instanceof Promise ? field : { then(cb: ((field: Opt<T>) => void)) { return cb(field); } };
+}
\ No newline at end of file
diff --git a/src/fields/URLField.ts b/src/fields/URLField.ts
new file mode 100644
index 000000000..fb71160ca
--- /dev/null
+++ b/src/fields/URLField.ts
@@ -0,0 +1,53 @@
+import { Deserializable } from "../client/util/SerializationHelper";
+import { serializable, custom } from "serializr";
+import { ObjectField } from "./ObjectField";
+import { ToScriptString, ToString, Copy } from "./FieldSymbols";
+import { Scripting, scriptingGlobal } from "../client/util/Scripting";
+
+function url() {
+    return custom(
+        function (value: URL) {
+            return value.href;
+        },
+        function (jsonValue: string) {
+            return new URL(jsonValue);
+        }
+    );
+}
+
+export abstract class URLField extends ObjectField {
+    @serializable(url())
+    readonly url: URL;
+
+    constructor(url: string);
+    constructor(url: URL);
+    constructor(url: URL | string) {
+        super();
+        if (typeof url === "string") {
+            url = new URL(url);
+        }
+        this.url = url;
+    }
+
+    [ToScriptString]() {
+        return `new ${this.constructor.name}("${this.url.href}")`;
+    }
+    [ToString]() {
+        return this.url.href;
+    }
+
+    [Copy](): this {
+        return new (this.constructor as any)(this.url);
+    }
+}
+
+export const nullAudio = "https://actions.google.com/sounds/v1/alarms/beep_short.ogg";
+
+@scriptingGlobal @Deserializable("audio") export class AudioField extends URLField { }
+@scriptingGlobal @Deserializable("image") export class ImageField extends URLField { }
+@scriptingGlobal @Deserializable("video") export class VideoField extends URLField { }
+@scriptingGlobal @Deserializable("pdf") export class PdfField extends URLField { }
+@scriptingGlobal @Deserializable("web") export class WebField extends URLField { }
+@scriptingGlobal @Deserializable("youtube") export class YoutubeField extends URLField { }
+@scriptingGlobal @Deserializable("webcam") export class WebCamField extends URLField { }
+
diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts
new file mode 100644
index 000000000..cacba43b6
--- /dev/null
+++ b/src/fields/documentSchemas.ts
@@ -0,0 +1,100 @@
+import { makeInterface, createSchema, listSpec } from "./Schema";
+import { ScriptField } from "./ScriptField";
+import { Doc } from "./Doc";
+import { DateField } from "./DateField";
+
+export const documentSchema = createSchema({
+    // content properties
+    type: "string",             // enumerated type of document -- should be template-specific (ie, start with an '_')
+    title: "string",            // document title (can be on either data document or layout)
+    isTemplateForField: "string",// if specified, it indicates the document is a template that renders the specified field
+    creationDate: DateField,    // when the document was created
+    links: listSpec(Doc),       // computed (readonly) list of links associated with this document
+
+    // "Location" properties in a very general sense
+    currentTimecode: "number",  // current play back time of a temporal document (video / audio)
+    displayTimecode: "number",  // the time that a document should be displayed (e.g., time an annotation should be displayed on a video)
+    inOverlay: "boolean",       // whether the document is rendered in an OverlayView which handles selection/dragging differently
+    x: "number",                // x coordinate when in a freeform view 
+    y: "number",                // y coordinate when in a freeform view 
+    z: "number",                // z "coordinate" - non-zero specifies the overlay layer of a freeformview
+    zIndex: "number",           // zIndex of a document in a freeform view
+    scrollY: "number",          // "command" to scroll a document to a position on load (the value will be reset to 0 after that )
+    scrollTop: "number",        // scroll position of a scrollable document (pdf, text, web)
+
+    // appearance properties on the layout
+    _autoHeight: "boolean",     // whether the height of the document should be computed automatically based on its contents
+    _nativeWidth: "number",     // native width of document which determines how much document contents are scaled when the document's width is set
+    _nativeHeight: "number",    // "
+    _width: "number",           // width of document in its container's coordinate system
+    _height: "number",          // "
+    _xPadding: "number",        // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
+    _yPadding: "number",        // pixels of padding on top/bottom of collectionfreeformview contents when fitToBox is set
+    _xMargin: "number",         // margin added on left/right of most documents to add separation from their container
+    _yMargin: "number",         // margin added on top/bottom of most documents to add separation from their container
+    _overflow: "string",        // sets overflow behvavior for CollectionFreeForm views
+    _showCaption: "string",     // whether editable caption text is overlayed at the bottom of the document 
+    _showTitle: "string",       // the fieldkey whose contents should be displayed at the top of the document
+    _showTitleHover: "string",  // the showTitle should be shown only on hover
+    _showAudio: "boolean",      // whether to show the audio record icon on documents
+    _freeformLayoutEngine: "string",// the string ID for the layout engine to use to layout freeform view documents
+    _LODdisable: "boolean",     // whether to disbale LOD switching for CollectionFreeFormViews
+    _pivotField: "string",      // specifies which field key should be used as the timeline/pivot axis
+    _replacedChrome: "string",  // what the default chrome is replaced with. Currently only supports the value of 'replaced' for PresBox's.
+    _chromeStatus: "string",    // determines the state of the collection chrome. values allowed are 'replaced', 'enabled', 'disabled', 'collapsed'
+    _fontSize: "number",
+    _fontFamily: "string",
+    _sidebarWidthPercent: "string", // percent of text window width taken up by sidebar
+
+    // appearance properties on the data document
+    backgroundColor: "string",  // background color of document
+    borderRounding: "string",   // border radius rounding of document
+    boxShadow: "string",        // the amount of shadow around the perimeter of a document
+    color: "string",            // foreground color of document
+    fitToBox: "boolean",        // whether freeform view contents should be zoomed/panned to fill the area of the document view
+    fontSize: "string",
+    layout: "string",           // this is the native layout string for the document.  templates can be added using other fields and setting layoutKey below
+    layoutKey: "string",        // holds the field key for the field that actually holds the current lyoat
+    letterSpacing: "string",
+    opacity: "number",          // opacity of document
+    strokeWidth: "number",
+    textTransform: "string",
+    treeViewOpen: "boolean",    //  flag denoting whether the documents sub-tree (contents) is visible or hidden
+    treeViewExpandedView: "string", // name of field whose contents are being displayed as the document's subtree
+    treeViewPreventOpen: "boolean", // ignores the treeViewOpen flag (for allowing a view to not be slaved to other views of the document)
+
+    // interaction and linking properties
+    ignoreClick: "boolean",     // whether documents ignores input clicks (but does not ignore manipulation and other events) 
+    onClick: ScriptField,       // script to run when document is clicked (can be overriden by an onClick prop)
+    onPointerDown: ScriptField, // script to run when document is clicked (can be overriden by an onClick prop)
+    onPointerUp: ScriptField,   // script to run when document is clicked (can be overriden by an onClick prop)
+    onDragStart: ScriptField,   // script to run when document is dragged (without being selected).  the script should return the Doc to be dropped.
+    followLinkLocation: "string",// flag for where to place content when following a click interaction (e.g., onRight, inPlace, inTab, ) 
+    isInPlaceContainer: "boolean",// whether the marked object will display addDocTab() calls that target "inPlace" destinations
+    isLinkButton: "boolean",    // whether document functions as a link follow button to follow the first link on the document when clicked   
+    isBackground: "boolean",    // whether document is a background element and ignores input events (can only select with marquee)
+    lockedPosition: "boolean",  // whether the document can be moved (dragged)
+    lockedTransform: "boolean", // whether the document can be panned/zoomed
+
+    // drag drop properties
+    dragFactory: Doc,           // the document that serves as the "template" for the onDragStart script.  ie, to drag out copies of the dragFactory document.
+    dropAction: "string",       // override specifying what should happen when this document is dropped (can be "alias", "copy", "move")
+    targetDropAction: "string", // allows the target of a drop event to specify the dropAction ("alias", "copy", "move") NOTE: if the document is dropped within the same collection, the dropAction is coerced to 'move'
+    childDropAction: "string",  // specify the override for what should happen when the child of a collection is dragged from it and dropped (can be "alias" or "copy")
+    removeDropProperties: listSpec("string"), // properties that should be removed from the alias/copy/etc of this document when it is dropped
+});
+
+
+export const collectionSchema = createSchema({
+    childLayoutTemplateName: "string", // the name of a template to use to override the layoutKey when rendering a document -- ONLY used in DocHolderBox 
+    childLayoutTemplate: Doc, // layout template to use to render children of a collecion
+    childLayoutString: "string", //layout string to use to render children of a collection
+    childClickedOpenTemplateView: Doc, // layout template to apply to a child when its clicked on in a collection and opened (requires onChildClick or other script to read this value and apply template)
+    dontRegisterChildViews: "boolean", // whether views made of this document are registered so that they can be found when drawing links scrollToLinkID: "string",   // id of link being traversed. allows this doc to scroll/highlight/etc its link anchor. scrollToLinkID should be set to undefined by this doc after it sets up its scroll,etc.
+    onChildClick: ScriptField, // script to run for each child when its clicked
+    onChildDoubleClick: ScriptField, // script to run for each child when its clicked
+    onCheckedClick: ScriptField, // script to run when a checkbox is clicked next to a child in a tree view
+});
+
+export type Document = makeInterface<[typeof documentSchema]>;
+export const Document = makeInterface(documentSchema);
diff --git a/src/fields/util.ts b/src/fields/util.ts
new file mode 100644
index 000000000..a287b0210
--- /dev/null
+++ b/src/fields/util.ts
@@ -0,0 +1,199 @@
+import { UndoManager } from "../client/util/UndoManager";
+import { Doc, Field, FieldResult, UpdatingFromServer, LayoutSym } from "./Doc";
+import { SerializationHelper } from "../client/util/SerializationHelper";
+import { ProxyField, PrefetchProxy } from "./Proxy";
+import { RefField } from "./RefField";
+import { ObjectField } from "./ObjectField";
+import { action, trace } from "mobx";
+import { Parent, OnUpdate, Update, Id, SelfProxy, Self } from "./FieldSymbols";
+import { DocServer } from "../client/DocServer";
+import { ComputedField } from "./ScriptField";
+import { ScriptCast } from "./Types";
+
+function _readOnlySetter(): never {
+    throw new Error("Documents can't be modified in read-only mode");
+}
+
+const tracing = false;
+export function TraceMobx() {
+    tracing && trace();
+}
+
+export interface GetterResult {
+    value: FieldResult;
+    shouldReturn?: boolean;
+}
+export type GetterPlugin = (receiver: any, prop: string | number, currentValue: any) => GetterResult | undefined;
+const getterPlugins: GetterPlugin[] = [];
+
+export namespace Plugins {
+    export function addGetterPlugin(plugin: GetterPlugin) {
+        getterPlugins.push(plugin);
+    }
+}
+
+const _setterImpl = action(function (target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
+    //console.log("-set " + target[SelfProxy].title + "(" + target[SelfProxy][prop] + ")." + prop.toString() + " = " + value);
+    if (SerializationHelper.IsSerializing()) {
+        target[prop] = value;
+        return true;
+    }
+
+    if (typeof prop === "symbol") {
+        target[prop] = value;
+        return true;
+    }
+    if (value !== undefined) {
+        value = value[SelfProxy] || value;
+    }
+    const curValue = target.__fields[prop];
+    if (curValue === value || (curValue instanceof ProxyField && value instanceof RefField && curValue.fieldId === value[Id])) {
+        // TODO This kind of checks correctly in the case that curValue is a ProxyField and value is a RefField, but technically
+        // curValue should get filled in with value if it isn't already filled in, in case we fetched the referenced field some other way
+        return true;
+    }
+    if (value instanceof RefField) {
+        value = new ProxyField(value);
+    }
+    if (value instanceof ObjectField) {
+        if (value[Parent] && value[Parent] !== receiver && !(value instanceof PrefetchProxy)) {
+            throw new Error("Can't put the same object in multiple documents at the same time");
+        }
+        value[Parent] = receiver;
+        value[OnUpdate] = updateFunction(target, prop, value, receiver);
+    }
+    if (curValue instanceof ObjectField) {
+        delete curValue[Parent];
+        delete curValue[OnUpdate];
+    }
+    const writeMode = DocServer.getFieldWriteMode(prop as string);
+    const fromServer = target[UpdatingFromServer];
+    const sameAuthor = fromServer || (receiver.author === Doc.CurrentUserEmail);
+    const writeToDoc = sameAuthor || (writeMode !== DocServer.WriteMode.LiveReadonly);
+    const writeToServer = sameAuthor || (writeMode === DocServer.WriteMode.Default);
+    if (writeToDoc) {
+        if (value === undefined) {
+            delete target.__fields[prop];
+        } else {
+            target.__fields[prop] = value;
+        }
+        if (typeof value === "object" && !(value instanceof ObjectField)) debugger;
+        if (writeToServer) {
+            if (value === undefined) target[Update]({ '$unset': { ["fields." + prop]: "" } });
+            else target[Update]({ '$set': { ["fields." + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) : (value === undefined ? null : value) } });
+        } else {
+            DocServer.registerDocWithCachedUpdate(receiver, prop as string, curValue);
+        }
+        UndoManager.AddEvent({
+            redo: () => receiver[prop] = value,
+            undo: () => receiver[prop] = curValue
+        });
+    }
+    return true;
+});
+
+let _setter: (target: any, prop: string | symbol | number, value: any, receiver: any) => boolean = _setterImpl;
+
+export function makeReadOnly() {
+    _setter = _readOnlySetter;
+}
+
+export function makeEditable() {
+    _setter = _setterImpl;
+}
+
+const layoutProps = ["panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "fitWidth", "fitToBox",
+    "LODdisable", "chromeStatus", "viewType", "gridGap", "xMargin", "yMargin", "autoHeight"];
+export function setter(target: any, in_prop: string | symbol | number, value: any, receiver: any): boolean {
+    let prop = in_prop;
+    if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && (prop.startsWith("_") || layoutProps.includes(prop))) {
+        if (!prop.startsWith("_")) {
+            console.log(prop + " is deprecated - switch to _" + prop);
+            prop = "_" + prop;
+        }
+        if (target.__LAYOUT__) {
+            target.__LAYOUT__[prop] = value;
+            return true;
+        }
+    }
+    if (target.__fields[prop] instanceof ComputedField && target.__fields[prop].setterscript) {
+        return ScriptCast(target.__fields[prop])?.setterscript?.run({ self: target[SelfProxy], this: target[SelfProxy], value }).success ? true : false;
+    }
+    return _setter(target, prop, value, receiver);
+}
+
+export function getter(target: any, in_prop: string | symbol | number, receiver: any): any {
+    let prop = in_prop;
+    if (prop === LayoutSym) {
+        return target.__LAYOUT__;
+    }
+    if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && (prop.startsWith("_") || layoutProps.includes(prop))) {
+        if (!prop.startsWith("_")) {
+            console.log(prop + " is deprecated - switch to _" + prop);
+            prop = "_" + prop;
+        }
+        if (target.__LAYOUT__) return target.__LAYOUT__[prop];
+    }
+    if (prop === "then") {//If we're being awaited
+        return undefined;
+    }
+    if (typeof prop === "symbol") {
+        return target.__fields[prop] || target[prop];
+    }
+    if (SerializationHelper.IsSerializing()) {
+        return target[prop];
+    }
+    return getFieldImpl(target, prop, receiver);
+}
+
+function getFieldImpl(target: any, prop: string | number, receiver: any, ignoreProto: boolean = false): any {
+    receiver = receiver || target[SelfProxy];
+    let field = target.__fields[prop];
+    for (const plugin of getterPlugins) {
+        const res = plugin(receiver, prop, field);
+        if (res === undefined) continue;
+        if (res.shouldReturn) {
+            return res.value;
+        } else {
+            field = res.value;
+        }
+    }
+    if (field === undefined && !ignoreProto && prop !== "proto") {
+        const proto = getFieldImpl(target, "proto", receiver, true);//TODO tfs: instead of receiver we could use target[SelfProxy]... I don't which semantics we want or if it really matters
+        if (proto instanceof Doc) {
+            return getFieldImpl(proto[Self], prop, receiver, ignoreProto);
+        }
+        return undefined;
+    }
+    return field;
+
+}
+export function getField(target: any, prop: string | number, ignoreProto: boolean = false): any {
+    return getFieldImpl(target, prop, undefined, ignoreProto);
+}
+
+export function deleteProperty(target: any, prop: string | number | symbol) {
+    if (typeof prop === "symbol") {
+        delete target[prop];
+        return true;
+    }
+    target[SelfProxy][prop] = undefined;
+    return true;
+}
+
+export function updateFunction(target: any, prop: any, value: any, receiver: any) {
+    let current = ObjectField.MakeCopy(value);
+    return (diff?: any) => {
+        if (true || !diff) {
+            diff = { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } };
+            const oldValue = current;
+            const newValue = ObjectField.MakeCopy(value);
+            current = newValue;
+            UndoManager.AddEvent({
+                redo() { receiver[prop] = newValue; },
+                undo() { receiver[prop] = oldValue; }
+            });
+        }
+        target[Update](diff);
+    };
+}
\ No newline at end of file
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index f30e9869a..231870531 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -4,10 +4,10 @@ import { Docs } from '../client/documents/Documents';
 import "./ImageUpload.scss";
 import React = require('react');
 import { DocServer } from '../client/DocServer';
-import { Opt, Doc } from '../new_fields/Doc';
-import { Cast } from '../new_fields/Types';
-import { listSpec } from '../new_fields/Schema';
-import { List } from '../new_fields/List';
+import { Opt, Doc } from '../fields/Doc';
+import { Cast } from '../fields/Types';
+import { listSpec } from '../fields/Schema';
+import { List } from '../fields/List';
 import { observer } from 'mobx-react';
 import { observable } from 'mobx';
 import { Utils } from '../Utils';
diff --git a/src/mobile/MobileInkOverlay.tsx b/src/mobile/MobileInkOverlay.tsx
index 1537ae034..973931615 100644
--- a/src/mobile/MobileInkOverlay.tsx
+++ b/src/mobile/MobileInkOverlay.tsx
@@ -4,11 +4,11 @@ import { MobileInkOverlayContent, GestureContent, UpdateMobileInkOverlayPosition
 import { observable, action } from "mobx";
 import { GestureUtils } from "../pen-gestures/GestureUtils";
 import "./MobileInkOverlay.scss";
-import { StrCast, Cast } from '../new_fields/Types';
+import { StrCast, Cast } from '../fields/Types';
 import { DragManager } from "../client/util/DragManager";
 import { DocServer } from '../client/DocServer';
-import { Doc, DocListCastAsync } from '../new_fields/Doc';
-import { listSpec } from '../new_fields/Schema';
+import { Doc, DocListCastAsync } from '../fields/Doc';
+import { listSpec } from '../fields/Schema';
 
 
 @observer
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 9d4d58ad1..6c2e797d6 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -16,12 +16,12 @@ import { InkingControl } from '../client/views/InkingControl';
 import { DocumentView } from '../client/views/nodes/DocumentView';
 import { RadialMenu } from '../client/views/nodes/RadialMenu';
 import { PreviewCursor } from '../client/views/PreviewCursor';
-import { Doc, DocListCast, FieldResult } from '../new_fields/Doc';
-import { Id } from '../new_fields/FieldSymbols';
-import { InkTool } from '../new_fields/InkField';
-import { listSpec } from '../new_fields/Schema';
-import { Cast, FieldValue } from '../new_fields/Types';
-import { WebField } from "../new_fields/URLField";
+import { Doc, DocListCast, FieldResult } from '../fields/Doc';
+import { Id } from '../fields/FieldSymbols';
+import { InkTool } from '../fields/InkField';
+import { listSpec } from '../fields/Schema';
+import { Cast, FieldValue } from '../fields/Types';
+import { WebField } from "../fields/URLField";
 import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
 import { emptyFunction, emptyPath, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero } from '../Utils';
 import "./MobileInterface.scss";
diff --git a/src/new_fields/CursorField.ts b/src/new_fields/CursorField.ts
deleted file mode 100644
index 28467377b..000000000
--- a/src/new_fields/CursorField.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import { ObjectField } from "./ObjectField";
-import { observable } from "mobx";
-import { Deserializable } from "../client/util/SerializationHelper";
-import { serializable, createSimpleSchema, object, date } from "serializr";
-import { OnUpdate, ToScriptString, ToString, Copy } from "./FieldSymbols";
-
-export type CursorPosition = {
-    x: number,
-    y: number
-};
-
-export type CursorMetadata = {
-    id: string,
-    identifier: string,
-    timestamp: number
-};
-
-export type CursorData = {
-    metadata: CursorMetadata,
-    position: CursorPosition
-};
-
-const PositionSchema = createSimpleSchema({
-    x: true,
-    y: true
-});
-
-const MetadataSchema = createSimpleSchema({
-    id: true,
-    identifier: true,
-    timestamp: true
-});
-
-const CursorSchema = createSimpleSchema({
-    metadata: object(MetadataSchema),
-    position: object(PositionSchema)
-});
-
-@Deserializable("cursor")
-export default class CursorField extends ObjectField {
-
-    @serializable(object(CursorSchema))
-    readonly data: CursorData;
-
-    constructor(data: CursorData) {
-        super();
-        this.data = data;
-    }
-
-    setPosition(position: CursorPosition) {
-        this.data.position = position;
-        this.data.metadata.timestamp = Date.now();
-        this[OnUpdate]();
-    }
-
-    [Copy]() {
-        return new CursorField(this.data);
-    }
-
-    [ToScriptString]() {
-        return "invalid";
-    }
-    [ToString]() {
-        return "invalid";
-    }
-}
\ No newline at end of file
diff --git a/src/new_fields/DateField.ts b/src/new_fields/DateField.ts
deleted file mode 100644
index a925148c2..000000000
--- a/src/new_fields/DateField.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { Deserializable } from "../client/util/SerializationHelper";
-import { serializable, date } from "serializr";
-import { ObjectField } from "./ObjectField";
-import { Copy, ToScriptString, ToString } from "./FieldSymbols";
-import { scriptingGlobal, Scripting } from "../client/util/Scripting";
-
-@scriptingGlobal
-@Deserializable("date")
-export class DateField extends ObjectField {
-    @serializable(date())
-    readonly date: Date;
-
-    constructor(date: Date = new Date()) {
-        super();
-        this.date = date;
-    }
-
-    [Copy]() {
-        return new DateField(this.date);
-    }
-
-    toString() {
-        return `${this.date.toISOString()}`;
-    }
-
-    [ToScriptString]() {
-        return `new DateField(new Date(${this.date.toISOString()}))`;
-    }
-    [ToString]() {
-        return this.date.toISOString();
-    }
-}
-
-Scripting.addGlobal(function d(...dateArgs: any[]) {
-    return new DateField(new (Date as any)(...dateArgs));
-});
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
deleted file mode 100644
index a1e1e11b1..000000000
--- a/src/new_fields/Doc.ts
+++ /dev/null
@@ -1,1109 +0,0 @@
-import { action, computed, observable, ObservableMap, runInAction } from "mobx";
-import { computedFn } from "mobx-utils";
-import { alias, map, serializable } from "serializr";
-import { DocServer } from "../client/DocServer";
-import { DocumentType } from "../client/documents/DocumentTypes";
-import { Scripting, scriptingGlobal } from "../client/util/Scripting";
-import { afterDocDeserialize, autoObject, Deserializable, SerializationHelper } from "../client/util/SerializationHelper";
-import { UndoManager } from "../client/util/UndoManager";
-import { intersectRect, Utils } from "../Utils";
-import { HandleUpdate, Id, OnUpdate, Parent, Self, SelfProxy, ToScriptString, ToString, Update, Copy } from "./FieldSymbols";
-import { List } from "./List";
-import { ObjectField } from "./ObjectField";
-import { PrefetchProxy, ProxyField } from "./Proxy";
-import { FieldId, RefField } from "./RefField";
-import { RichTextField } from "./RichTextField";
-import { listSpec } from "./Schema";
-import { ComputedField, ScriptField } from "./ScriptField";
-import { Cast, FieldValue, NumCast, StrCast, ToConstructor, ScriptCast } from "./Types";
-import { deleteProperty, getField, getter, makeEditable, makeReadOnly, setter, updateFunction } from "./util";
-import { Docs, DocumentOptions } from "../client/documents/Documents";
-import { PdfField, VideoField, AudioField, ImageField } from "./URLField";
-import { LinkManager } from "../client/util/LinkManager";
-
-export namespace Field {
-    export function toKeyValueString(doc: Doc, key: string): string {
-        const onDelegate = Object.keys(doc).includes(key);
-
-        const field = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
-        if (Field.IsField(field)) {
-            return (onDelegate ? "=" : "") + (field instanceof ComputedField ? `:=${field.script.originalScript}` : Field.toScriptString(field));
-        }
-        return "";
-    }
-    export function toScriptString(field: Field): string {
-        if (typeof field === "string") {
-            return `"${field}"`;
-        } else if (typeof field === "number" || typeof field === "boolean") {
-            return String(field);
-        } else {
-            return field[ToScriptString]();
-        }
-    }
-    export function toString(field: Field): string {
-        if (typeof field === "string") {
-            return field;
-        } else if (typeof field === "number" || typeof field === "boolean") {
-            return String(field);
-        } else if (field instanceof ObjectField) {
-            return field[ToString]();
-        } else if (field instanceof RefField) {
-            return field[ToString]();
-        }
-        return "";
-    }
-    export function IsField(field: any): field is Field;
-    export function IsField(field: any, includeUndefined: true): field is Field | undefined;
-    export function IsField(field: any, includeUndefined: boolean = false): field is Field | undefined {
-        return (typeof field === "string")
-            || (typeof field === "number")
-            || (typeof field === "boolean")
-            || (field instanceof ObjectField)
-            || (field instanceof RefField)
-            || (includeUndefined && field === undefined);
-    }
-}
-export type Field = number | string | boolean | ObjectField | RefField;
-export type Opt<T> = T | undefined;
-export type FieldWaiting<T extends RefField = RefField> = T extends undefined ? never : Promise<T | undefined>;
-export type FieldResult<T extends Field = Field> = Opt<T> | FieldWaiting<Extract<T, RefField>>;
-
-/**
- * Cast any field to either a List of Docs or undefined if the given field isn't a List of Docs.  
- * If a default value is given, that will be returned instead of undefined.  
- * If a default value is given, the returned value should not be modified as it might be a temporary value.  
- * If no default value is given, and the returned value is not undefined, it can be safely modified.  
- */
-export function DocListCastAsync(field: FieldResult): Promise<Doc[] | undefined>;
-export function DocListCastAsync(field: FieldResult, defaultValue: Doc[]): Promise<Doc[]>;
-export function DocListCastAsync(field: FieldResult, defaultValue?: Doc[]) {
-    const list = Cast(field, listSpec(Doc));
-    return list ? Promise.all(list).then(() => list) : Promise.resolve(defaultValue);
-}
-
-export async function DocCastAsync(field: FieldResult): Promise<Opt<Doc>> {
-    return Cast(field, Doc);
-}
-
-export function DocListCast(field: FieldResult): Doc[] {
-    return Cast(field, listSpec(Doc), []).filter(d => d instanceof Doc) as Doc[];
-}
-
-export const WidthSym = Symbol("Width");
-export const HeightSym = Symbol("Height");
-export const DataSym = Symbol("Data");
-export const LayoutSym = Symbol("Layout");
-export const UpdatingFromServer = Symbol("UpdatingFromServer");
-const CachedUpdates = Symbol("Cached updates");
-
-
-function fetchProto(doc: Doc) {
-    const proto = doc.proto;
-    if (proto instanceof Promise) {
-        return proto;
-    }
-}
-
-@scriptingGlobal
-@Deserializable("Doc", fetchProto).withFields(["id"])
-export class Doc extends RefField {
-    constructor(id?: FieldId, forceSave?: boolean) {
-        super(id);
-        const doc = new Proxy<this>(this, {
-            set: setter,
-            get: getter,
-            // getPrototypeOf: (target) => Cast(target[SelfProxy].proto, Doc) || null, // TODO this might be able to replace the proto logic in getter
-            has: (target, key) => key in target.__fields,
-            ownKeys: target => {
-                const obj = {} as any;
-                Object.assign(obj, target.___fields);
-                runInAction(() => obj.__LAYOUT__ = target.__LAYOUT__);
-                return Object.keys(obj);
-            },
-            getOwnPropertyDescriptor: (target, prop) => {
-                if (prop.toString() === "__LAYOUT__") {
-                    return Reflect.getOwnPropertyDescriptor(target, prop);
-                }
-                if (prop in target.__fields) {
-                    return {
-                        configurable: true,//TODO Should configurable be true?
-                        enumerable: true,
-                        value: target.__fields[prop]
-                    };
-                }
-                return Reflect.getOwnPropertyDescriptor(target, prop);
-            },
-            deleteProperty: deleteProperty,
-            defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
-        });
-        this[SelfProxy] = doc;
-        if (!id || forceSave) {
-            DocServer.CreateField(doc);
-        }
-        return doc;
-    }
-
-    proto: Opt<Doc>;
-    [key: string]: FieldResult;
-
-    @serializable(alias("fields", map(autoObject(), { afterDeserialize: afterDocDeserialize })))
-    private get __fields() { return this.___fields; }
-    private set __fields(value) {
-        this.___fields = value;
-        for (const key in value) {
-            const field = value[key];
-            if (!(field instanceof ObjectField)) continue;
-            field[Parent] = this[Self];
-            field[OnUpdate] = updateFunction(this[Self], key, field, this[SelfProxy]);
-        }
-    }
-
-    @observable
-    //{ [key: string]: Field | FieldWaiting | undefined }
-    private ___fields: any = {};
-
-    private [UpdatingFromServer]: boolean = false;
-
-    private [Update] = (diff: any) => {
-        !this[UpdatingFromServer] && DocServer.UpdateField(this[Id], diff);
-    }
-
-    private [Self] = this;
-    private [SelfProxy]: any;
-    public [WidthSym] = () => NumCast(this[SelfProxy]._width);
-    public [HeightSym] = () => NumCast(this[SelfProxy]._height);
-    public get [LayoutSym]() { return this[SelfProxy].__LAYOUT__; }
-    public get [DataSym]() {
-        const self = this[SelfProxy];
-        return self.resolvedDataDoc && !self.isTemplateForField ? self :
-            Doc.GetProto(Cast(Doc.Layout(self).resolvedDataDoc, Doc, null) || self);
-    }
-    @computed get __LAYOUT__() {
-        const templateLayoutDoc = Cast(Doc.LayoutField(this[SelfProxy]), Doc, null);
-        if (templateLayoutDoc) {
-            let renderFieldKey: any;
-            const layoutField = templateLayoutDoc[StrCast(templateLayoutDoc.layoutKey, "layout")];
-            if (typeof layoutField === "string") {
-                renderFieldKey = layoutField.split("fieldKey={'")[1].split("'")[0];//layoutField.split("'")[1];
-            } else {
-                return Cast(layoutField, Doc, null);
-            }
-            return Cast(this[SelfProxy][renderFieldKey + "-layout[" + templateLayoutDoc[Id] + "]"], Doc, null) || templateLayoutDoc;
-        }
-        return undefined;
-    }
-
-    [ToScriptString]() { return `DOC-"${this[Self][Id]}"-`; }
-    [ToString]() { return `Doc(${this.title})`; }
-
-    private [CachedUpdates]: { [key: string]: () => void | Promise<any> } = {};
-    public static CurrentUserEmail: string = "";
-    public async [HandleUpdate](diff: any) {
-        const set = diff.$set;
-        const sameAuthor = this.author === Doc.CurrentUserEmail;
-        if (set) {
-            for (const key in set) {
-                if (!key.startsWith("fields.")) {
-                    continue;
-                }
-                const fKey = key.substring(7);
-                const fn = async () => {
-                    const value = await SerializationHelper.Deserialize(set[key]);
-                    this[UpdatingFromServer] = true;
-                    this[fKey] = value;
-                    this[UpdatingFromServer] = false;
-                };
-                if (sameAuthor || DocServer.getFieldWriteMode(fKey) !== DocServer.WriteMode.Playground) {
-                    delete this[CachedUpdates][fKey];
-                    await fn();
-                } else {
-                    this[CachedUpdates][fKey] = fn;
-                }
-            }
-        }
-        const unset = diff.$unset;
-        if (unset) {
-            for (const key in unset) {
-                if (!key.startsWith("fields.")) {
-                    continue;
-                }
-                const fKey = key.substring(7);
-                const fn = () => {
-                    this[UpdatingFromServer] = true;
-                    delete this[fKey];
-                    this[UpdatingFromServer] = false;
-                };
-                if (sameAuthor || DocServer.getFieldWriteMode(fKey) !== DocServer.WriteMode.Playground) {
-                    delete this[CachedUpdates][fKey];
-                    await fn();
-                } else {
-                    this[CachedUpdates][fKey] = fn;
-                }
-            }
-        }
-    }
-}
-
-export namespace Doc {
-    // export function GetAsync(doc: Doc, key: string, ignoreProto: boolean = false): Promise<Field | undefined> {
-    //     const self = doc[Self];
-    //     return new Promise(res => getField(self, key, ignoreProto, res));
-    // }
-    // export function GetTAsync<T extends Field>(doc: Doc, key: string, ctor: ToConstructor<T>, ignoreProto: boolean = false): Promise<T | undefined> {
-    //     return new Promise(async res => {
-    //         const field = await GetAsync(doc, key, ignoreProto);
-    //         return Cast(field, ctor);
-    //     });
-    // }
-
-    export function RunCachedUpdate(doc: Doc, field: string) {
-        const update = doc[CachedUpdates][field];
-        if (update) {
-            update();
-            delete doc[CachedUpdates][field];
-        }
-    }
-    export function AddCachedUpdate(doc: Doc, field: string, oldValue: any) {
-        const val = oldValue;
-        doc[CachedUpdates][field] = () => {
-            doc[UpdatingFromServer] = true;
-            doc[field] = val;
-            doc[UpdatingFromServer] = false;
-        };
-    }
-    export function MakeReadOnly(): { end(): void } {
-        makeReadOnly();
-        return {
-            end() {
-                makeEditable();
-            }
-        };
-    }
-
-    export function Get(doc: Doc, key: string, ignoreProto: boolean = false): FieldResult {
-        try {
-            return getField(doc[Self], key, ignoreProto);
-        } catch  {
-            return doc;
-        }
-    }
-    export function GetT<T extends Field>(doc: Doc, key: string, ctor: ToConstructor<T>, ignoreProto: boolean = false): FieldResult<T> {
-        return Cast(Get(doc, key, ignoreProto), ctor) as FieldResult<T>;
-    }
-    export function IsPrototype(doc: Doc) {
-        return GetT(doc, "isPrototype", "boolean", true);
-    }
-    export function IsBaseProto(doc: Doc) {
-        return GetT(doc, "baseProto", "boolean", true);
-    }
-    export async function SetInPlace(doc: Doc, key: string, value: Field | undefined, defaultProto: boolean) {
-        const hasProto = doc.proto instanceof Doc;
-        const onDeleg = Object.getOwnPropertyNames(doc).indexOf(key) !== -1;
-        const onProto = hasProto && Object.getOwnPropertyNames(doc.proto).indexOf(key) !== -1;
-        if (onDeleg || !hasProto || (!onProto && !defaultProto)) {
-            doc[key] = value;
-        } else doc.proto![key] = value;
-    }
-    export async function SetOnPrototype(doc: Doc, key: string, value: Field) {
-        const proto = Object.getOwnPropertyNames(doc).indexOf("isPrototype") === -1 ? doc.proto : doc;
-
-        if (proto) {
-            proto[key] = value;
-        }
-    }
-    export function GetAllPrototypes(doc: Doc): Doc[] {
-        const protos: Doc[] = [];
-        let d: Opt<Doc> = doc;
-        while (d) {
-            protos.push(d);
-            d = FieldValue(d.proto);
-        }
-        return protos;
-    }
-
-    /**
-     * This function is intended to model Object.assign({}, {}) [https://mzl.la/1Mo3l21], which copies
-     * the values of the properties of a source object into the target.
-     * 
-     * This is just a specific, Dash-authored version that serves the same role for our
-     * Doc class.
-     * 
-     * @param doc the target document into which you'd like to insert the new fields 
-     * @param fields the fields to project onto the target. Its type signature defines a mapping from some string key
-     * to a potentially undefined field, where each entry in this mapping is optional. 
-     */
-    export function assign<K extends string>(doc: Doc, fields: Partial<Record<K, Opt<Field>>>, skipUndefineds: boolean = false) {
-        for (const key in fields) {
-            if (fields.hasOwnProperty(key)) {
-                const value = fields[key];
-                if (!skipUndefineds || value !== undefined) { // Do we want to filter out undefineds?
-                    doc[key] = value;
-                }
-            }
-        }
-        return doc;
-    }
-
-    // compare whether documents or their protos match
-    export function AreProtosEqual(doc?: Doc, other?: Doc) {
-        if (!doc || !other) return false;
-        const r = (doc === other);
-        const r2 = (Doc.GetProto(doc) === other);
-        const r3 = (Doc.GetProto(other) === doc);
-        const r4 = (Doc.GetProto(doc) === Doc.GetProto(other) && Doc.GetProto(other) !== undefined);
-        return r || r2 || r3 || r4;
-    }
-
-    // Gets the data document for the document.  Note: this is mis-named -- it does not specifically
-    // return the doc's proto, but rather recursively searches through the proto inheritance chain 
-    // and returns the document who's proto is undefined or whose proto is marked as a base prototype ('isPrototype').
-    export function GetProto(doc: Doc): Doc {
-        if (doc instanceof Promise) {
-            console.log("GetProto: error: got Promise insead of Doc");
-        }
-        const proto = doc && (Doc.GetT(doc, "isPrototype", "boolean", true) ? doc : (doc.proto || doc));
-        return proto === doc ? proto : Doc.GetProto(proto);
-    }
-    export function GetDataDoc(doc: Doc): Doc {
-        const proto = Doc.GetProto(doc);
-        return proto === doc ? proto : Doc.GetDataDoc(proto);
-    }
-
-    export function allKeys(doc: Doc): string[] {
-        const results: Set<string> = new Set;
-
-        let proto: Doc | undefined = doc;
-        while (proto) {
-            Object.keys(proto).forEach(key => results.add(key));
-            proto = proto.proto;
-        }
-
-        return Array.from(results);
-    }
-
-    export function IndexOf(toFind: Doc, list: Doc[], allowProtos: boolean = true) {
-        let index = list.reduce((p, v, i) => (v instanceof Doc && v === toFind) ? i : p, -1);
-        index = allowProtos && index !== -1 ? index : list.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, toFind)) ? i : p, -1);
-        return index; // list.findIndex(doc => doc === toFind || Doc.AreProtosEqual(doc, toFind));
-    }
-    export function RemoveDocFromList(listDoc: Doc, fieldKey: string | undefined, doc: Doc) {
-        const key = fieldKey ? fieldKey : Doc.LayoutFieldKey(listDoc);
-        if (listDoc[key] === undefined) {
-            Doc.GetProto(listDoc)[key] = new List<Doc>();
-        }
-        const list = Cast(listDoc[key], listSpec(Doc));
-        if (list) {
-            const ind = list.indexOf(doc);
-            if (ind !== -1) {
-                list.splice(ind, 1);
-                return true;
-            }
-        }
-        return false;
-    }
-    export function AddDocToList(listDoc: Doc, fieldKey: string | undefined, doc: Doc, relativeTo?: Doc, before?: boolean, first?: boolean, allowDuplicates?: boolean, reversed?: boolean) {
-        const key = fieldKey ? fieldKey : Doc.LayoutFieldKey(listDoc);
-        if (listDoc[key] === undefined) {
-            Doc.GetProto(listDoc)[key] = new List<Doc>();
-        }
-        const list = Cast(listDoc[key], listSpec(Doc));
-        if (list) {
-            if (allowDuplicates !== true) {
-                const pind = list.reduce((l, d, i) => d instanceof Doc && d[Id] === doc[Id] ? i : l, -1);
-                if (pind !== -1) {
-                    list.splice(pind, 1);
-                }
-            }
-            if (first) {
-                list.splice(0, 0, doc);
-            }
-            else {
-                const ind = relativeTo ? list.indexOf(relativeTo) : -1;
-                if (ind === -1) {
-                    if (reversed) list.splice(0, 0, doc);
-                    else list.push(doc);
-                }
-                else {
-                    if (reversed) list.splice(before ? (list.length - ind) + 1 : list.length - ind, 0, doc);
-                    else list.splice(before ? ind : ind + 1, 0, doc);
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
-    //
-    // Computes the bounds of the contents of a set of documents.
-    //
-    export function ComputeContentBounds(docList: Doc[]) {
-        const bounds = docList.reduce((bounds, doc) => {
-            const [sptX, sptY] = [NumCast(doc.x), NumCast(doc.y)];
-            const [bptX, bptY] = [sptX + doc[WidthSym](), sptY + doc[HeightSym]()];
-            return {
-                x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
-                r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
-            };
-        }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: -Number.MAX_VALUE, b: -Number.MAX_VALUE });
-        return bounds;
-    }
-
-    export function MakeAlias(doc: Doc, id?: string) {
-        const alias = !GetT(doc, "isPrototype", "boolean", true) ? Doc.MakeCopy(doc, undefined, id) : Doc.MakeDelegate(doc, id);
-        const layout = Doc.LayoutField(alias);
-        if (layout instanceof Doc && layout !== alias && layout === Doc.Layout(alias)) {
-            Doc.SetLayout(alias, Doc.MakeAlias(layout));
-        }
-        alias.aliasOf = doc;
-        alias.title = ComputedField.MakeFunction(`renameAlias(this, ${Doc.GetProto(doc).aliasNumber = NumCast(Doc.GetProto(doc).aliasNumber) + 1})`);
-        return alias;
-    }
-
-    //
-    // Determines whether the layout needs to be expanded (as a template).
-    // template expansion is rquired when the layout is a template doc/field and there's a datadoc which isn't equal to the layout template
-    //
-    export function WillExpandTemplateLayout(layoutDoc: Doc, dataDoc?: Doc) {
-        return (layoutDoc.isTemplateForField || layoutDoc.isTemplateDoc) && dataDoc && layoutDoc !== dataDoc;
-    }
-
-    const _pendingMap: Map<string, boolean> = new Map();
-    //
-    // Returns an expanded template layout for a target data document if there is a template relationship
-    // between the two. If so, the layoutDoc is expanded into a new document that inherits the properties 
-    // of the original layout while allowing for individual layout properties to be overridden in the expanded layout.
-    // templateArgs should be equivalent to the layout key that generates the template since that's where the template parameters are stored in ()'s at the end of the key.
-    // NOTE:  the template will have references to "@params" -- the template arguments will be assigned to the '@params' field
-    // so that when the @params key is accessed, it will be rewritten as the key that is stored in the 'params' field and
-    // the derefence will then occur on the rootDocument (the original document).
-    // in the future, field references could be written as @<someparam> and then arguments would be passed in the layout key as:
-    //   layout_mytemplate(somparam=somearg).   
-    // then any references to @someparam would be rewritten as accesses to 'somearg' on the rootDocument
-    export function expandTemplateLayout(templateLayoutDoc: Doc, targetDoc?: Doc, templateArgs?: string) {
-        const args = templateArgs?.match(/\(([a-zA-Z0-9._\-]*)\)/)?.[1].replace("()", "") || StrCast(templateLayoutDoc.PARAMS);
-        if (!args && !WillExpandTemplateLayout(templateLayoutDoc, targetDoc) || !targetDoc) return templateLayoutDoc;
-
-        const templateField = StrCast(templateLayoutDoc.isTemplateForField);  // the field that the template renders
-        // First it checks if an expanded layout already exists -- if so it will be stored on the dataDoc
-        // using the template layout doc's id as the field key.
-        // If it doesn't find the expanded layout, then it makes a delegate of the template layout and
-        // saves it on the data doc indexed by the template layout's id.
-        //
-        const params = args.split("=").length > 1 ? args.split("=")[0] : "PARAMS";
-        const layoutFielddKey = Doc.LayoutFieldKey(templateLayoutDoc);
-        const expandedLayoutFieldKey = (templateField || layoutFielddKey) + "-layout[" + templateLayoutDoc[Id] + (args ? `(${args})` : "") + "]";
-        let expandedTemplateLayout = targetDoc?.[expandedLayoutFieldKey];
-
-        if (templateLayoutDoc.resolvedDataDoc instanceof Promise) {
-            expandedTemplateLayout = undefined;
-            _pendingMap.set(targetDoc[Id] + expandedLayoutFieldKey, true);
-        }
-        else if (expandedTemplateLayout === undefined && !_pendingMap.get(targetDoc[Id] + expandedLayoutFieldKey + args)) {
-            if (templateLayoutDoc.resolvedDataDoc === (targetDoc.rootDocument || Doc.GetProto(targetDoc)) && templateLayoutDoc.PARAMS === StrCast(targetDoc.PARAMS)) {
-                expandedTemplateLayout = templateLayoutDoc; // reuse an existing template layout if its for the same document with the same params
-            } else {
-                _pendingMap.set(targetDoc[Id] + expandedLayoutFieldKey + args, true);
-                templateLayoutDoc.resolvedDataDoc && (templateLayoutDoc = Cast(templateLayoutDoc.proto, Doc, null) || templateLayoutDoc); // if the template has already been applied (ie, a nested template), then use the template's prototype
-                setTimeout(action(() => {
-                    if (!targetDoc[expandedLayoutFieldKey]) {
-                        const newLayoutDoc = Doc.MakeDelegate(templateLayoutDoc, undefined, "[" + templateLayoutDoc.title + "]");
-                        // the template's arguments are stored in params which is derefenced to find
-                        // the actual field key where the parameterized template data is stored.
-                        newLayoutDoc[params] = args !== "..." ? args : ""; // ... signifies the layout has sub template(s) -- so we have to expand the layout for them so that they can get the correct 'rootDocument' field, but we don't need to reassign their params.  it would be better if the 'rootDocument' field could be passed dynamically to avoid have to create instances
-                        newLayoutDoc.rootDocument = targetDoc;
-                        targetDoc[expandedLayoutFieldKey] = newLayoutDoc;
-                        const dataDoc = Doc.GetProto(targetDoc);
-                        newLayoutDoc.resolvedDataDoc = dataDoc;
-                        if (dataDoc[templateField] === undefined && templateLayoutDoc[templateField] instanceof List) {
-                            dataDoc[templateField] = ComputedField.MakeFunction(`ObjectField.MakeCopy(templateLayoutDoc["${templateField}"] as List)`, { templateLayoutDoc: Doc.name }, { templateLayoutDoc });
-                        }
-                        _pendingMap.delete(targetDoc[Id] + expandedLayoutFieldKey + args);
-                    }
-                }), 0);
-            }
-        }
-        return expandedTemplateLayout instanceof Doc ? expandedTemplateLayout : undefined; // layout is undefined if the expandedTemplateLayout is pending.
-    }
-
-    // if the childDoc is a template for a field, then this will return the expanded layout with its data doc.
-    // otherwise, it just returns the childDoc
-    export function GetLayoutDataDocPair(containerDoc: Doc, containerDataDoc: Opt<Doc>, childDoc: Doc) {
-        if (!childDoc || childDoc instanceof Promise || !Doc.GetProto(childDoc)) {
-            console.log("No, no, no!");
-            return { layout: childDoc, data: childDoc };
-        }
-        const resolvedDataDoc = (Doc.AreProtosEqual(containerDataDoc, containerDoc) || (!childDoc.isTemplateDoc && !childDoc.isTemplateForField && !childDoc.PARAMS) ? undefined : containerDataDoc);
-        return { layout: Doc.expandTemplateLayout(childDoc, resolvedDataDoc, "(" + StrCast(containerDoc.PARAMS) + ")"), data: resolvedDataDoc };
-    }
-
-    export function Overwrite(doc: Doc, overwrite: Doc, copyProto: boolean = false): Doc {
-        Object.keys(doc).forEach(key => {
-            const field = ProxyField.WithoutProxy(() => doc[key]);
-            if (key === "proto" && copyProto) {
-                if (doc.proto instanceof Doc && overwrite.proto instanceof Doc) {
-                    overwrite[key] = Doc.Overwrite(doc[key]!, overwrite.proto);
-                }
-            } else {
-                if (field instanceof RefField) {
-                    overwrite[key] = field;
-                } else if (field instanceof ObjectField) {
-                    overwrite[key] = ObjectField.MakeCopy(field);
-                } else if (field instanceof Promise) {
-                    debugger; //This shouldn't happend...
-                } else {
-                    overwrite[key] = field;
-                }
-            }
-        });
-
-        return overwrite;
-    }
-
-    export function MakeCopy(doc: Doc, copyProto: boolean = false, copyProtoId?: string): Doc {
-        const copy = new Doc(copyProtoId, true);
-        const exclude = Cast(doc.excludeFields, listSpec("string"), []);
-        Object.keys(doc).forEach(key => {
-            if (exclude.includes(key)) return;
-            const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
-            const field = ProxyField.WithoutProxy(() => doc[key]);
-            if (key === "proto" && copyProto) {
-                if (doc[key] instanceof Doc) {
-                    copy[key] = Doc.MakeCopy(doc[key]!, false);
-                }
-            } else {
-                if (field instanceof RefField) {
-                    copy[key] = field;
-                } else if (cfield instanceof ComputedField) {
-                    copy[key] = ComputedField.MakeFunction(cfield.script.originalScript);
-                } else if (field instanceof ObjectField) {
-                    copy[key] = doc[key] instanceof Doc ?
-                        key.includes("layout[") ? Doc.MakeCopy(doc[key] as Doc, false) : doc[key] : // reference documents except copy documents that are expanded teplate fields 
-                        ObjectField.MakeCopy(field);
-                } else if (field instanceof Promise) {
-                    debugger; //This shouldn't happend...
-                } else {
-                    copy[key] = field;
-                }
-            }
-        });
-
-        return copy;
-    }
-
-    export function MakeClone(doc: Doc): Doc {
-        const cloneMap = new Map<string, Doc>();
-        const rtfMap: { copy: Doc, key: string, field: RichTextField }[] = [];
-        const copy = Doc.makeClone(doc, cloneMap, rtfMap);
-        rtfMap.map(({ copy, key, field }) => {
-            const replacer = (match: any, attr: string, id: string, offset: any, string: any) => {
-                const mapped = cloneMap.get(id);
-                return attr + "\"" + (mapped ? mapped[Id] : id) + "\"";
-            };
-            const replacer2 = (match: any, href: string, id: string, offset: any, string: any) => {
-                const mapped = cloneMap.get(id);
-                return href + (mapped ? mapped[Id] : id);
-            };
-            const regex = `(${Utils.prepend("/doc/")})([^"]*)`;
-            const re = new RegExp(regex, "g");
-            copy[key] = new RichTextField(field.Data.replace(/("docid":|"targetId":|"linkId":)"([^"]+)"/g, replacer).replace(re, replacer2), field.Text);
-        });
-        return copy;
-    }
-
-    export function makeClone(doc: Doc, cloneMap: Map<string, Doc>, rtfs: { copy: Doc, key: string, field: RichTextField }[]): Doc {
-        if (Doc.IsBaseProto(doc)) return doc;
-        if (cloneMap.get(doc[Id])) return cloneMap.get(doc[Id])!;
-        const copy = new Doc(undefined, true);
-        cloneMap.set(doc[Id], copy);
-        if (LinkManager.Instance.getAllLinks().includes(doc) && LinkManager.Instance.getAllLinks().indexOf(copy) === -1) LinkManager.Instance.addLink(copy);
-        const exclude = Cast(doc.excludeFields, listSpec("string"), []);
-        Object.keys(doc).forEach(key => {
-            if (exclude.includes(key)) return;
-            const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
-            const field = ProxyField.WithoutProxy(() => doc[key]);
-            const copyObjectField = (field: ObjectField) => {
-                const list = Cast(doc[key], listSpec(Doc));
-                if (list !== undefined && !(list instanceof Promise)) {
-                    copy[key] = new List<Doc>(list.filter(d => d instanceof Doc).map(d => Doc.makeClone(d as Doc, cloneMap, rtfs)));
-                } else if (doc[key] instanceof Doc) {
-                    copy[key] = key.includes("layout[") ? undefined : Doc.makeClone(doc[key] as Doc, cloneMap, rtfs); // reference documents except copy documents that are expanded teplate fields 
-                } else {
-                    copy[key] = ObjectField.MakeCopy(field);
-                    if (field instanceof RichTextField) {
-                        if (field.Data.includes('"docid":') || field.Data.includes('"targetId":') || field.Data.includes('"linkId":')) {
-                            rtfs.push({ copy, key, field });
-                        }
-                    }
-                }
-            };
-            if (key === "proto") {
-                if (doc[key] instanceof Doc) {
-                    copy[key] = Doc.makeClone(doc[key]!, cloneMap, rtfs);
-                }
-            } else {
-                if (field instanceof RefField) {
-                    copy[key] = field;
-                } else if (cfield instanceof ComputedField) {
-                    copy[key] = ComputedField.MakeFunction(cfield.script.originalScript);
-                    (key === "links" && field instanceof ObjectField) && copyObjectField(field);
-                } else if (field instanceof ObjectField) {
-                    copyObjectField(field);
-                } else if (field instanceof Promise) {
-                    debugger; //This shouldn't happend...
-                } else {
-                    copy[key] = field;
-                }
-            }
-        });
-        Doc.SetInPlace(copy, "title", "CLONE: " + doc.title, true);
-        copy.cloneOf = doc;
-        cloneMap.set(doc[Id], copy);
-        return copy;
-    }
-
-    export function MakeDelegate(doc: Doc, id?: string, title?: string): Doc;
-    export function MakeDelegate(doc: Opt<Doc>, id?: string, title?: string): Opt<Doc>;
-    export function MakeDelegate(doc: Opt<Doc>, id?: string, title?: string): Opt<Doc> {
-        if (doc) {
-            const delegate = new Doc(id, true);
-            delegate.proto = doc;
-            title && (delegate.title = title);
-            return delegate;
-        }
-        return undefined;
-    }
-
-    let _applyCount: number = 0;
-    export function ApplyTemplate(templateDoc: Doc) {
-        if (templateDoc) {
-            const target = Doc.MakeDelegate(new Doc());
-            const targetKey = StrCast(templateDoc.layoutKey, "layout");
-            const applied = ApplyTemplateTo(templateDoc, target, targetKey, templateDoc.title + "(..." + _applyCount++ + ")");
-            target.layoutKey = targetKey;
-            applied && (Doc.GetProto(applied).type = templateDoc.type);
-            return applied;
-        }
-        return undefined;
-    }
-    export function ApplyTemplateTo(templateDoc: Doc, target: Doc, targetKey: string, titleTarget: string | undefined) {
-        if (!Doc.AreProtosEqual(target[targetKey] as Doc, templateDoc)) {
-            if (target.resolvedDataDoc) {
-                target[targetKey] = new PrefetchProxy(templateDoc);
-            } else {
-                titleTarget && (Doc.GetProto(target).title = titleTarget);
-                Doc.GetProto(target)[targetKey] = new PrefetchProxy(templateDoc);
-            }
-        }
-        return target;
-    }
-
-    //
-    //  This function converts a generic field layout display into a field layout that displays a specific
-    // metadata field indicated by the title of the template field (not the default field that it was rendering)
-    //
-    export function MakeMetadataFieldTemplate(templateField: Doc, templateDoc: Opt<Doc>): boolean {
-
-        // find the metadata field key that this template field doc will display (indicated by its title)
-        const metadataFieldKey = StrCast(templateField.isTemplateForField) || StrCast(templateField.title).replace(/^-/, "");
-
-        // update the original template to mark it as a template
-        templateField.isTemplateForField = metadataFieldKey;
-        templateField.title = metadataFieldKey;
-
-        const templateFieldValue = templateField[metadataFieldKey] || templateField[Doc.LayoutFieldKey(templateField)];
-        const templateCaptionValue = templateField.caption;
-        // move any data that the template field had been rendering over to the template doc so that things will still be rendered
-        // when the template field is adjusted to point to the new metadatafield key.
-        // note 1: if the template field contained a list of documents, each of those documents will be converted to templates as well.
-        // note 2: this will not overwrite any field that already exists on the template doc at the field key
-        if (!templateDoc?.[metadataFieldKey] && templateFieldValue instanceof ObjectField) {
-            Cast(templateFieldValue, listSpec(Doc), [])?.map(d => d instanceof Doc && MakeMetadataFieldTemplate(d, templateDoc));
-            (Doc.GetProto(templateField)[metadataFieldKey] = ObjectField.MakeCopy(templateFieldValue));
-        }
-        // copy the textTemplates from 'this' (not 'self') because the layout contains the template info, not the original doc
-        if (templateCaptionValue instanceof RichTextField && !templateCaptionValue.Empty()) {
-            templateField["caption-textTemplate"] = ComputedField.MakeFunction(`copyField(this.caption)`);
-        }
-        if (templateFieldValue instanceof RichTextField && !templateFieldValue.Empty()) {
-            templateField[metadataFieldKey + "-textTemplate"] = ComputedField.MakeFunction(`copyField(this.${metadataFieldKey})`);
-        }
-
-        // get the layout string that the template uses to specify its layout
-        const templateFieldLayoutString = StrCast(Doc.LayoutField(Doc.Layout(templateField)));
-
-        // change it to render the target metadata field instead of what it was rendering before and assign it to the template field layout document.
-        Doc.Layout(templateField).layout = templateFieldLayoutString.replace(/fieldKey={'[^']*'}/, `fieldKey={'${metadataFieldKey}'}`);
-
-        // assign the template field doc a delegate of any extension document that was previously used to render the template field (since extension doc's carry rendering informatino)
-        Doc.Layout(templateField)[metadataFieldKey + "_ext"] = Doc.MakeDelegate(templateField[templateFieldLayoutString?.split("'")[1] + "_ext"] as Doc);
-
-        return true;
-    }
-
-    export function overlapping(doc1: Doc, doc2: Doc, clusterDistance: number) {
-        const doc2Layout = Doc.Layout(doc2);
-        const doc1Layout = Doc.Layout(doc1);
-        const x2 = NumCast(doc2.x) - clusterDistance;
-        const y2 = NumCast(doc2.y) - clusterDistance;
-        const w2 = NumCast(doc2Layout._width) + clusterDistance;
-        const h2 = NumCast(doc2Layout._height) + clusterDistance;
-        const x = NumCast(doc1.x) - clusterDistance;
-        const y = NumCast(doc1.y) - clusterDistance;
-        const w = NumCast(doc1Layout._width) + clusterDistance;
-        const h = NumCast(doc1Layout._height) + clusterDistance;
-        return doc1.z === doc2.z && intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 });
-    }
-
-    export function isBrushedHighlightedDegree(doc: Doc) {
-        if (Doc.IsHighlighted(doc)) {
-            return 6;
-        }
-        else {
-            return Doc.IsBrushedDegree(doc);
-        }
-    }
-
-    export class DocBrush {
-        BrushedDoc: ObservableMap<Doc, boolean> = new ObservableMap();
-    }
-    const brushManager = new DocBrush();
-
-    export class DocData {
-        @observable _user_doc: Doc = undefined!;
-        @observable _searchQuery: string = "";
-    }
-
-    // the document containing the view layout information - will be the Document itself unless the Document has
-    // a layout field or 'layout' is given.  
-    export function Layout(doc: Doc, layout?: Doc): Doc {
-        const overrideLayout = layout && Cast(doc[`${StrCast(layout.isTemplateForField, "data")}-layout[` + layout[Id] + "]"], Doc, null);
-        return overrideLayout || doc[LayoutSym] || doc;
-    }
-    export function SetLayout(doc: Doc, layout: Doc | string) { doc[StrCast(doc.layoutKey, "layout")] = layout; }
-    export function LayoutField(doc: Doc) { return doc[StrCast(doc.layoutKey, "layout")]; }
-    export function LayoutFieldKey(doc: Doc): string { return StrCast(Doc.Layout(doc).layout).split("'")[1]; }
-    const manager = new DocData();
-    export function SearchQuery(): string { return manager._searchQuery; }
-    export function SetSearchQuery(query: string) { runInAction(() => manager._searchQuery = query); }
-    export function UserDoc(): Doc { return manager._user_doc; }
-    export function SetUserDoc(doc: Doc) { manager._user_doc = doc; }
-    export function IsBrushed(doc: Doc) {
-        return computedFn(function IsBrushed(doc: Doc) {
-            return brushManager.BrushedDoc.has(doc) || brushManager.BrushedDoc.has(Doc.GetProto(doc));
-        })(doc);
-    }
-    // don't bother memoizing (caching) the result if called from a non-reactive context. (plus this avoids a warning message)
-    export function IsBrushedDegreeUnmemoized(doc: Doc) {
-        return brushManager.BrushedDoc.has(doc) ? 2 : brushManager.BrushedDoc.has(Doc.GetProto(doc)) ? 1 : 0;
-    }
-    export function IsBrushedDegree(doc: Doc) {
-        return computedFn(function IsBrushDegree(doc: Doc) {
-            return Doc.IsBrushedDegreeUnmemoized(doc);
-        })(doc);
-    }
-    export function BrushDoc(doc: Doc) {
-        brushManager.BrushedDoc.set(doc, true);
-        brushManager.BrushedDoc.set(Doc.GetProto(doc), true);
-        return doc;
-    }
-    export function UnBrushDoc(doc: Doc) {
-        brushManager.BrushedDoc.delete(doc);
-        brushManager.BrushedDoc.delete(Doc.GetProto(doc));
-        return doc;
-    }
-
-
-    export function LinkOtherAnchor(linkDoc: Doc, anchorDoc: Doc) { return Doc.AreProtosEqual(anchorDoc, Cast(linkDoc.anchor1, Doc) as Doc) ? Cast(linkDoc.anchor2, Doc) as Doc : Cast(linkDoc.anchor1, Doc) as Doc; }
-    export function LinkEndpoint(linkDoc: Doc, anchorDoc: Doc) { return Doc.AreProtosEqual(anchorDoc, Cast(linkDoc.anchor1, Doc) as Doc) ? "1" : "2"; }
-
-    export function linkFollowUnhighlight() {
-        Doc.UnhighlightAll();
-        document.removeEventListener("pointerdown", linkFollowUnhighlight);
-    }
-
-    let _lastDate = 0;
-    export function linkFollowHighlight(destDoc: Doc, dataAndDisplayDocs = true) {
-        linkFollowUnhighlight();
-        Doc.HighlightDoc(destDoc, dataAndDisplayDocs);
-        document.removeEventListener("pointerdown", linkFollowUnhighlight);
-        document.addEventListener("pointerdown", linkFollowUnhighlight);
-        const lastDate = _lastDate = Date.now();
-        window.setTimeout(() => _lastDate === lastDate && linkFollowUnhighlight(), 5000);
-    }
-
-    export class HighlightBrush {
-        @observable HighlightedDoc: Map<Doc, boolean> = new Map();
-    }
-    const highlightManager = new HighlightBrush();
-    export function IsHighlighted(doc: Doc) {
-        return highlightManager.HighlightedDoc.get(doc) || highlightManager.HighlightedDoc.get(Doc.GetProto(doc));
-    }
-    export function HighlightDoc(doc: Doc, dataAndDisplayDocs = true) {
-        runInAction(() => {
-            highlightManager.HighlightedDoc.set(doc, true);
-            dataAndDisplayDocs && highlightManager.HighlightedDoc.set(Doc.GetProto(doc), true);
-        });
-    }
-    export function UnHighlightDoc(doc: Doc) {
-        runInAction(() => {
-            highlightManager.HighlightedDoc.set(doc, false);
-            highlightManager.HighlightedDoc.set(Doc.GetProto(doc), false);
-        });
-    }
-    export function UnhighlightAll() {
-        const mapEntries = highlightManager.HighlightedDoc.keys();
-        let docEntry: IteratorResult<Doc>;
-        while (!(docEntry = mapEntries.next()).done) {
-            const targetDoc = docEntry.value;
-            targetDoc && Doc.UnHighlightDoc(targetDoc);
-        }
-
-    }
-    export function UnBrushAllDocs() {
-        brushManager.BrushedDoc.clear();
-    }
-
-    export function getDocTemplate(doc?: Doc) {
-        return doc?.isTemplateDoc ? doc :
-            Cast(doc?.dragFactory, Doc, null)?.isTemplateDoc ? doc?.dragFactory :
-                Cast(doc?.layout, Doc, null)?.isTemplateDoc ? doc?.layout : undefined;
-    }
-
-    export function matchFieldValue(doc: Doc, key: string, value: any): boolean {
-        const fieldVal = doc[key];
-        if (Cast(fieldVal, listSpec("string"), []).length) {
-            const vals = Cast(fieldVal, listSpec("string"), []);
-            return vals.some(v => v === value);
-        }
-        const fieldStr = Field.toString(fieldVal as Field);
-        return fieldStr === value;
-    }
-
-    export function deiconifyView(doc: any) {
-        StrCast(doc.layoutKey).split("_")[1] === "icon" && setNativeView(doc);
-    }
-
-    export function setNativeView(doc: any) {
-        const prevLayout = StrCast(doc.layoutKey).split("_")[1];
-        const deiconify = prevLayout === "icon" && StrCast(doc.deiconifyLayout) ? "layout_" + StrCast(doc.deiconifyLayout) : "";
-        prevLayout === "icon" && (doc.deiconifyLayout = undefined);
-        doc.layoutKey = deiconify || "layout";
-    }
-    export function setDocFilterRange(target: Doc, key: string, range?: number[]) {
-        const docRangeFilters = Cast(target._docRangeFilters, listSpec("string"), []);
-        for (let i = 0; i < docRangeFilters.length; i += 3) {
-            if (docRangeFilters[i] === key) {
-                docRangeFilters.splice(i, 3);
-                break;
-            }
-        }
-        if (range !== undefined) {
-            docRangeFilters.push(key);
-            docRangeFilters.push(range[0].toString());
-            docRangeFilters.push(range[1].toString());
-            target._docRangeFilters = new List<string>(docRangeFilters);
-        }
-    }
-
-    export function aliasDocs(field: any) {
-        return new List<Doc>(field.map((d: any) => Doc.MakeAlias(d)));
-    }
-
-    // filters document in a container collection:
-    // all documents with the specified value for the specified key are included/excluded 
-    // based on the modifiers :"check", "x", undefined
-    export function setDocFilter(container: Doc, key: string, value: any, modifiers?: "check" | "x" | undefined) {
-        const docFilters = Cast(container._docFilters, listSpec("string"), []);
-        for (let i = 0; i < docFilters.length; i += 3) {
-            if (docFilters[i] === key && docFilters[i + 1] === value) {
-                docFilters.splice(i, 3);
-                break;
-            }
-        }
-        if (typeof modifiers === "string") {
-            docFilters.push(key);
-            docFilters.push(value);
-            docFilters.push(modifiers);
-            container._docFilters = new List<string>(docFilters);
-        }
-    }
-    export function readDocRangeFilter(doc: Doc, key: string) {
-        const docRangeFilters = Cast(doc._docRangeFilters, listSpec("string"), []);
-        for (let i = 0; i < docRangeFilters.length; i += 3) {
-            if (docRangeFilters[i] === key) {
-                return [Number(docRangeFilters[i + 1]), Number(docRangeFilters[i + 2])];
-            }
-        }
-    }
-    export function assignDocToField(doc: Doc, field: string, id: string) {
-        DocServer.GetRefField(id).then(layout => layout instanceof Doc && (doc[field] = layout));
-        return id;
-    }
-
-    export function toggleNativeDimensions(layoutDoc: Doc, contentScale: number, panelWidth: number, panelHeight: number) {
-        runInAction(() => {
-            if (layoutDoc._nativeWidth || layoutDoc._nativeHeight) {
-                layoutDoc.scale = NumCast(layoutDoc.scale, 1) * contentScale;
-                layoutDoc._nativeWidth = undefined;
-                layoutDoc._nativeHeight = undefined;
-            }
-            else {
-                layoutDoc._autoHeight = false;
-                if (!layoutDoc._nativeWidth) {
-                    layoutDoc._nativeWidth = NumCast(layoutDoc._width, panelWidth);
-                    layoutDoc._nativeHeight = NumCast(layoutDoc._height, panelHeight);
-                }
-            }
-        });
-    }
-
-    export function isDocPinned(doc: Doc) {
-        //add this new doc to props.Document
-        const curPres = Cast(Doc.UserDoc().activePresentation, Doc) as Doc;
-        if (curPres) {
-            return DocListCast(curPres.data).findIndex((val) => Doc.AreProtosEqual(val, doc)) !== -1;
-        }
-        return false;
-    }
-
-    // applies a custom template to a document.  the template is identified by it's short name (e.g, slideView not layout_slideView)
-    export function makeCustomViewClicked(doc: Doc, creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, templateSignature: string = "custom", docLayoutTemplate?: Doc) {
-        const batch = UndoManager.StartBatch("makeCustomViewClicked");
-        runInAction(() => {
-            doc.layoutKey = "layout_" + templateSignature;
-            if (doc[doc.layoutKey] === undefined) {
-                createCustomView(doc, creator, templateSignature, docLayoutTemplate);
-            }
-        });
-        batch.end();
-    }
-    export function findTemplate(templateName: string, type: string, signature: string) {
-        let docLayoutTemplate: Opt<Doc>;
-        const iconViews = DocListCast(Cast(Doc.UserDoc()["template-icons"], Doc, null)?.data);
-        const templBtns = DocListCast(Cast(Doc.UserDoc()["template-buttons"], Doc, null)?.data);
-        const noteTypes = DocListCast(Cast(Doc.UserDoc()["template-notes"], Doc, null)?.data);
-        const clickFuncs = DocListCast(Cast(Doc.UserDoc().clickFuncs, Doc, null)?.data);
-        const allTemplates = iconViews.concat(templBtns).concat(noteTypes).concat(clickFuncs).map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc);
-        // bcz: this is hacky -- want to have different templates be applied depending on the "type" of a document.  but type is not reliable and there could be other types of template searches so this should be generalized
-        // first try to find a template that matches the specific document type (<typeName>_<templateName>).  otherwise, fallback to a general match on <templateName>
-        !docLayoutTemplate && allTemplates.forEach(tempDoc => StrCast(tempDoc.title) === templateName + "_" + type && (docLayoutTemplate = tempDoc));
-        !docLayoutTemplate && allTemplates.forEach(tempDoc => StrCast(tempDoc.title) === templateName && (docLayoutTemplate = tempDoc));
-        return docLayoutTemplate;
-    }
-    export function createCustomView(doc: Doc, creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, templateSignature: string = "custom", docLayoutTemplate?: Doc) {
-        const templateName = templateSignature.replace(/\(.*\)/, "");
-        docLayoutTemplate = docLayoutTemplate || findTemplate(templateName, StrCast(doc.type), templateSignature);
-
-        const customName = "layout_" + templateSignature;
-        const _width = NumCast(doc._width);
-        const _height = NumCast(doc._height);
-        const options = { title: "data", backgroundColor: StrCast(doc.backgroundColor), _autoHeight: true, _width, x: -_width / 2, y: - _height / 2, _showSidebar: false };
-
-        let fieldTemplate: Opt<Doc>;
-        if (doc.data instanceof RichTextField || typeof (doc.data) === "string") {
-            fieldTemplate = Docs.Create.TextDocument("", options);
-        } else if (doc.data instanceof PdfField) {
-            fieldTemplate = Docs.Create.PdfDocument("http://www.msn.com", options);
-        } else if (doc.data instanceof VideoField) {
-            fieldTemplate = Docs.Create.VideoDocument("http://www.cs.brown.edu", options);
-        } else if (doc.data instanceof AudioField) {
-            fieldTemplate = Docs.Create.AudioDocument("http://www.cs.brown.edu", options);
-        } else if (doc.data instanceof ImageField) {
-            fieldTemplate = Docs.Create.ImageDocument("http://www.cs.brown.edu", options);
-        }
-        const docTemplate = docLayoutTemplate || creator?.(fieldTemplate ? [fieldTemplate] : [], { title: customName + "(" + doc.title + ")", isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) });
-
-        fieldTemplate && Doc.MakeMetadataFieldTemplate(fieldTemplate, docTemplate ? Doc.GetProto(docTemplate) : docTemplate);
-        docTemplate && Doc.ApplyTemplateTo(docTemplate, doc, customName, undefined);
-    }
-    export function makeCustomView(doc: Doc, custom: boolean, layout: string) {
-        Doc.setNativeView(doc);
-        if (custom) {
-            makeCustomViewClicked(doc, Docs.Create.StackingDocument, layout, undefined);
-        }
-    }
-    export function iconify(doc: Doc) {
-        const layoutKey = Cast(doc.layoutKey, "string", null);
-        Doc.makeCustomViewClicked(doc, Docs.Create.StackingDocument, "icon", undefined);
-        if (layoutKey && layoutKey !== "layout" && layoutKey !== "layout_icon") doc.deiconifyLayout = layoutKey.replace("layout_", "");
-    }
-
-    export function pileup(selected: Doc[], x: number, y: number) {
-        const newCollection = Docs.Create.PileDocument(selected, { title: "pileup", x: x - 55, y: y - 55, _width: 110, _height: 100, _LODdisable: true });
-        let w = 0, h = 0;
-        selected.forEach((d, i) => {
-            Doc.iconify(d);
-            w = Math.max(d[WidthSym](), w);
-            h = Math.max(d[HeightSym](), h);
-        });
-        h = Math.max(h, w * 4 / 3); // converting to an icon does not update the height right away.  so this is a fallback hack to try to do something reasonable
-        selected.forEach((d, i) => {
-            d.x = Math.cos(Math.PI * 2 * i / selected.length) * 10 - w / 2;
-            d.y = Math.sin(Math.PI * 2 * i / selected.length) * 10 - h / 2;
-            d.displayTimecode = undefined;  // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
-        });
-        newCollection.x = NumCast(newCollection.x) + NumCast(newCollection._width) / 2 - 55;
-        newCollection.y = NumCast(newCollection.y) + NumCast(newCollection._height) / 2 - 55;
-        newCollection._width = newCollection._height = 110;
-        //newCollection.borderRounding = "40px";
-        newCollection._jitterRotation = 10;
-        newCollection._backgroundColor = "gray";
-        newCollection._overflow = "visible";
-        return newCollection;
-    }
-
-
-    export async function addFieldEnumerations(doc: Opt<Doc>, enumeratedFieldKey: string, enumerations: { title: string, _backgroundColor?: string, color?: string }[]) {
-        let optionsCollection = await DocServer.GetRefField(enumeratedFieldKey);
-        if (!(optionsCollection instanceof Doc)) {
-            optionsCollection = Docs.Create.StackingDocument([], { title: `${enumeratedFieldKey} field set` }, enumeratedFieldKey);
-            Doc.AddDocToList((Doc.UserDoc().fieldTypes as Doc), "data", optionsCollection as Doc);
-        }
-        const options = optionsCollection as Doc;
-        const targetDoc = doc && Doc.GetProto(Cast(doc.rootDocument, Doc, null) || doc);
-        const docFind = `options.data.find(doc => doc.title === (this.rootDocument||this)["${enumeratedFieldKey}"])?`;
-        targetDoc && (targetDoc.backgroundColor = ComputedField.MakeFunction(docFind + `._backgroundColor || "white"`, undefined, { options }));
-        targetDoc && (targetDoc.color = ComputedField.MakeFunction(docFind + `.color || "black"`, undefined, { options }));
-        targetDoc && (targetDoc.borderRounding = ComputedField.MakeFunction(docFind + `.borderRounding`, undefined, { options }));
-        enumerations.map(enumeration => {
-            const found = DocListCast(options.data).find(d => d.title === enumeration.title);
-            if (found) {
-                found._backgroundColor = enumeration._backgroundColor || found._backgroundColor;
-                found._color = enumeration.color || found._color;
-            } else {
-                Doc.AddDocToList(options, "data", Docs.Create.TextDocument(enumeration.title, enumeration));
-            }
-        });
-        return optionsCollection;
-    }
-}
-
-Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(Doc.GetProto(doc).title).replace(/\([0-9]*\)/, "") + `(${n})`; });
-Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); });
-Scripting.addGlobal(function getDocTemplate(doc?: any) { return Doc.getDocTemplate(doc); });
-Scripting.addGlobal(function getAlias(doc: any) { return Doc.MakeAlias(doc); });
-Scripting.addGlobal(function getCopy(doc: any, copyProto: any) { return doc.isTemplateDoc ? Doc.ApplyTemplate(doc) : Doc.MakeCopy(doc, copyProto); });
-Scripting.addGlobal(function copyField(field: any) { return ObjectField.MakeCopy(field); });
-Scripting.addGlobal(function aliasDocs(field: any) { return Doc.aliasDocs(field); });
-Scripting.addGlobal(function docList(field: any) { return DocListCast(field); });
-Scripting.addGlobal(function setInPlace(doc: any, field: any, value: any) { return Doc.SetInPlace(doc, field, value, false); });
-Scripting.addGlobal(function sameDocs(doc1: any, doc2: any) { return Doc.AreProtosEqual(doc1, doc2); });
-Scripting.addGlobal(function deiconifyView(doc: any) { Doc.deiconifyView(doc); });
-Scripting.addGlobal(function undo() { return UndoManager.Undo(); });
-Scripting.addGlobal(function redo() { return UndoManager.Redo(); });
-Scripting.addGlobal(function DOC(id: string) { console.log("Can't parse a document id in a script"); return "invalid"; });
-Scripting.addGlobal(function assignDoc(doc: Doc, field: string, id: string) { return Doc.assignDocToField(doc, field, id); });
-Scripting.addGlobal(function docCast(doc: FieldResult): any { return DocCastAsync(doc); });
-Scripting.addGlobal(function activePresentationItem() {
-    const curPres = Doc.UserDoc().activePresentation as Doc;
-    return curPres && DocListCast(curPres[Doc.LayoutFieldKey(curPres)])[NumCast(curPres._itemIndex)];
-});
-Scripting.addGlobal(function selectDoc(doc: any) { Doc.UserDoc().activeSelection = new List([doc]); });
-Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) {
-    const docs = DocListCast(Doc.UserDoc().activeSelection).
-        filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.DOCHOLDER && d.type !== DocumentType.KVP &&
-            (!excludeCollections || d.type !== DocumentType.COL || !Cast(d.data, listSpec(Doc), null)));
-    return docs.length ? new List(docs) : prevValue;
-});
-Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: any, modifiers?: "check" | "x" | undefined) { Doc.setDocFilter(container, key, value, modifiers); });
-Scripting.addGlobal(function setDocFilterRange(container: Doc, key: string, range: number[]) { Doc.setDocFilterRange(container, key, range); });
\ No newline at end of file
diff --git a/src/new_fields/FieldSymbols.ts b/src/new_fields/FieldSymbols.ts
deleted file mode 100644
index 8d040f493..000000000
--- a/src/new_fields/FieldSymbols.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-
-export const Update = Symbol("Update");
-export const Self = Symbol("Self");
-export const SelfProxy = Symbol("SelfProxy");
-export const HandleUpdate = Symbol("HandleUpdate");
-export const Id = Symbol("Id");
-export const OnUpdate = Symbol("OnUpdate");
-export const Parent = Symbol("Parent");
-export const Copy = Symbol("Copy");
-export const ToScriptString = Symbol("ToScriptString");
-export const ToPlainText = Symbol("ToPlainText");
-export const ToString = Symbol("ToString");
diff --git a/src/new_fields/HtmlField.ts b/src/new_fields/HtmlField.ts
deleted file mode 100644
index 6e8bba977..000000000
--- a/src/new_fields/HtmlField.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { Deserializable } from "../client/util/SerializationHelper";
-import { serializable, primitive } from "serializr";
-import { ObjectField } from "./ObjectField";
-import { Copy, ToScriptString, ToString} from "./FieldSymbols";
-
-@Deserializable("html")
-export class HtmlField extends ObjectField {
-    @serializable(primitive())
-    readonly html: string;
-
-    constructor(html: string) {
-        super();
-        this.html = html;
-    }
-
-    [Copy]() {
-        return new HtmlField(this.html);
-    }
-
-    [ToScriptString]() {
-        return "invalid";
-    }
-    [ToString]() {
-        return this.html;
-    }
-}
diff --git a/src/new_fields/IconField.ts b/src/new_fields/IconField.ts
deleted file mode 100644
index 76c4ddf1b..000000000
--- a/src/new_fields/IconField.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { Deserializable } from "../client/util/SerializationHelper";
-import { serializable, primitive } from "serializr";
-import { ObjectField } from "./ObjectField";
-import { Copy, ToScriptString, ToString } from "./FieldSymbols";
-
-@Deserializable("icon")
-export class IconField extends ObjectField {
-    @serializable(primitive())
-    readonly icon: string;
-
-    constructor(icon: string) {
-        super();
-        this.icon = icon;
-    }
-
-    [Copy]() {
-        return new IconField(this.icon);
-    }
-
-    [ToScriptString]() {
-        return "invalid";
-    }
-    [ToString]() {
-        return "ICONfield";
-    }
-}
diff --git a/src/new_fields/InkField.ts b/src/new_fields/InkField.ts
deleted file mode 100644
index bb93de5ac..000000000
--- a/src/new_fields/InkField.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { Deserializable } from "../client/util/SerializationHelper";
-import { serializable, custom, createSimpleSchema, list, object, map } from "serializr";
-import { ObjectField } from "./ObjectField";
-import { Copy, ToScriptString, ToString } from "./FieldSymbols";
-
-export enum InkTool {
-    None,
-    Pen,
-    Highlighter,
-    Eraser,
-    Stamp
-}
-
-export interface PointData {
-    X: number;
-    Y: number;
-}
-
-export type InkData = Array<PointData>;
-
-const pointSchema = createSimpleSchema({
-    X: true, Y: true
-});
-
-const strokeDataSchema = createSimpleSchema({
-    pathData: list(object(pointSchema)),
-    "*": true
-});
-
-@Deserializable("ink")
-export class InkField extends ObjectField {
-    @serializable(list(object(strokeDataSchema)))
-    readonly inkData: InkData;
-
-    constructor(data: InkData) {
-        super();
-        this.inkData = data;
-    }
-
-    [Copy]() {
-        return new InkField(this.inkData);
-    }
-
-    [ToScriptString]() {
-        return "invalid";
-    }
-    [ToString]() {
-        return "InkField";
-    }
-}
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
deleted file mode 100644
index fdabea365..000000000
--- a/src/new_fields/List.ts
+++ /dev/null
@@ -1,330 +0,0 @@
-import { Deserializable, autoObject, afterDocDeserialize } from "../client/util/SerializationHelper";
-import { Field } from "./Doc";
-import { setter, getter, deleteProperty, updateFunction } from "./util";
-import { serializable, alias, list } from "serializr";
-import { observable, action, runInAction } from "mobx";
-import { ObjectField } from "./ObjectField";
-import { RefField } from "./RefField";
-import { ProxyField } from "./Proxy";
-import { Self, Update, Parent, OnUpdate, SelfProxy, ToScriptString, ToString, Copy, Id } from "./FieldSymbols";
-import { Scripting } from "../client/util/Scripting";
-import { DocServer } from "../client/DocServer";
-
-const listHandlers: any = {
-    /// Mutator methods
-    copyWithin() {
-        throw new Error("copyWithin not supported yet");
-    },
-    fill(value: any, start?: number, end?: number) {
-        if (value instanceof RefField) {
-            throw new Error("fill with RefFields not supported yet");
-        }
-        const res = this[Self].__fields.fill(value, start, end);
-        this[Update]();
-        return res;
-    },
-    pop(): any {
-        const field = toRealField(this[Self].__fields.pop());
-        this[Update]();
-        return field;
-    },
-    push: action(function (this: any, ...items: any[]) {
-        items = items.map(toObjectField);
-        const list = this[Self];
-        const length = list.__fields.length;
-        for (let i = 0; i < items.length; i++) {
-            const item = items[i];
-            //TODO Error checking to make sure parent doesn't already exist
-            if (item instanceof ObjectField) {
-                item[Parent] = list;
-                item[OnUpdate] = updateFunction(list, i + length, item, this);
-            }
-        }
-        const res = list.__fields.push(...items);
-        this[Update]();
-        return res;
-    }),
-    reverse() {
-        const res = this[Self].__fields.reverse();
-        this[Update]();
-        return res;
-    },
-    shift() {
-        const res = toRealField(this[Self].__fields.shift());
-        this[Update]();
-        return res;
-    },
-    sort(cmpFunc: any) {
-        this[Self].__realFields(); // coerce retrieving entire array
-        const res = this[Self].__fields.sort(cmpFunc ? (first: any, second: any) => cmpFunc(toRealField(first), toRealField(second)) : undefined);
-        this[Update]();
-        return res;
-    },
-    splice: action(function (this: any, start: number, deleteCount: number, ...items: any[]) {
-        this[Self].__realFields(); // coerce retrieving entire array
-        items = items.map(toObjectField);
-        const list = this[Self];
-        for (let i = 0; i < items.length; i++) {
-            const item = items[i];
-            //TODO Error checking to make sure parent doesn't already exist
-            //TODO Need to change indices of other fields in array
-            if (item instanceof ObjectField) {
-                item[Parent] = list;
-                item[OnUpdate] = updateFunction(list, i + start, item, this);
-            }
-        }
-        const res = list.__fields.splice(start, deleteCount, ...items);
-        this[Update]();
-        return res.map(toRealField);
-    }),
-    unshift(...items: any[]) {
-        items = items.map(toObjectField);
-        const list = this[Self];
-        const length = list.__fields.length;
-        for (let i = 0; i < items.length; i++) {
-            const item = items[i];
-            //TODO Error checking to make sure parent doesn't already exist
-            //TODO Need to change indices of other fields in array
-            if (item instanceof ObjectField) {
-                item[Parent] = list;
-                item[OnUpdate] = updateFunction(list, i, item, this);
-            }
-        }
-        const res = this[Self].__fields.unshift(...items);
-        this[Update]();
-        return res;
-
-    },
-    /// Accessor methods
-    concat: action(function (this: any, ...items: any[]) {
-        this[Self].__realFields();
-        return this[Self].__fields.map(toRealField).concat(...items);
-    }),
-    includes(valueToFind: any, fromIndex: number) {
-        if (valueToFind instanceof RefField) {
-            return this[Self].__realFields().includes(valueToFind, fromIndex);
-        } else {
-            return this[Self].__fields.includes(valueToFind, fromIndex);
-        }
-    },
-    indexOf(valueToFind: any, fromIndex: number) {
-        if (valueToFind instanceof RefField) {
-            return this[Self].__realFields().indexOf(valueToFind, fromIndex);
-        } else {
-            return this[Self].__fields.indexOf(valueToFind, fromIndex);
-        }
-    },
-    join(separator: any) {
-        this[Self].__realFields();
-        return this[Self].__fields.map(toRealField).join(separator);
-    },
-    lastIndexOf(valueToFind: any, fromIndex: number) {
-        if (valueToFind instanceof RefField) {
-            return this[Self].__realFields().lastIndexOf(valueToFind, fromIndex);
-        } else {
-            return this[Self].__fields.lastIndexOf(valueToFind, fromIndex);
-        }
-    },
-    slice(begin: number, end: number) {
-        this[Self].__realFields();
-        return this[Self].__fields.slice(begin, end).map(toRealField);
-    },
-
-    /// Iteration methods
-    entries() {
-        return this[Self].__realFields().entries();
-    },
-    every(callback: any, thisArg: any) {
-        return this[Self].__realFields().every(callback, thisArg);
-        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
-        // If we don't want to support the array parameter, we should use this version instead
-        // return this[Self].__fields.every((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
-    },
-    filter(callback: any, thisArg: any) {
-        return this[Self].__realFields().filter(callback, thisArg);
-        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
-        // If we don't want to support the array parameter, we should use this version instead
-        // return this[Self].__fields.filter((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
-    },
-    find(callback: any, thisArg: any) {
-        return this[Self].__realFields().find(callback, thisArg);
-        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
-        // If we don't want to support the array parameter, we should use this version instead
-        // return this[Self].__fields.find((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
-    },
-    findIndex(callback: any, thisArg: any) {
-        return this[Self].__realFields().findIndex(callback, thisArg);
-        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
-        // If we don't want to support the array parameter, we should use this version instead
-        // return this[Self].__fields.findIndex((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
-    },
-    forEach(callback: any, thisArg: any) {
-        return this[Self].__realFields().forEach(callback, thisArg);
-        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
-        // If we don't want to support the array parameter, we should use this version instead
-        // return this[Self].__fields.forEach((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
-    },
-    map(callback: any, thisArg: any) {
-        return this[Self].__realFields().map(callback, thisArg);
-        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
-        // If we don't want to support the array parameter, we should use this version instead
-        // return this[Self].__fields.map((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
-    },
-    reduce(callback: any, initialValue: any) {
-        return this[Self].__realFields().reduce(callback, initialValue);
-        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
-        // If we don't want to support the array parameter, we should use this version instead
-        // return this[Self].__fields.reduce((acc:any, element:any, index:number, array:any) => callback(acc, toRealField(element), index, array), initialValue);
-    },
-    reduceRight(callback: any, initialValue: any) {
-        return this[Self].__realFields().reduceRight(callback, initialValue);
-        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
-        // If we don't want to support the array parameter, we should use this version instead
-        // return this[Self].__fields.reduceRight((acc:any, element:any, index:number, array:any) => callback(acc, toRealField(element), index, array), initialValue);
-    },
-    some(callback: any, thisArg: any) {
-        return this[Self].__realFields().some(callback, thisArg);
-        // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
-        // If we don't want to support the array parameter, we should use this version instead
-        // return this[Self].__fields.some((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
-    },
-    values() {
-        return this[Self].__realFields().values();
-    },
-    [Symbol.iterator]() {
-        return this[Self].__realFields().values();
-    }
-};
-
-function toObjectField(field: Field) {
-    return field instanceof RefField ? new ProxyField(field) : field;
-}
-
-function toRealField(field: Field) {
-    return field instanceof ProxyField ? field.value() : field;
-}
-
-function listGetter(target: any, prop: string | number | symbol, receiver: any): any {
-    if (listHandlers.hasOwnProperty(prop)) {
-        return listHandlers[prop];
-    }
-    return getter(target, prop, receiver);
-}
-
-interface ListSpliceUpdate<T> {
-    type: "splice";
-    index: number;
-    added: T[];
-    removedCount: number;
-}
-
-interface ListIndexUpdate<T> {
-    type: "update";
-    index: number;
-    newValue: T;
-}
-
-type ListUpdate<T> = ListSpliceUpdate<T> | ListIndexUpdate<T>;
-
-type StoredType<T extends Field> = T extends RefField ? ProxyField<T> : T;
-
-@Deserializable("list")
-class ListImpl<T extends Field> extends ObjectField {
-    constructor(fields?: T[]) {
-        super();
-        const list = new Proxy<this>(this, {
-            set: setter,
-            get: listGetter,
-            ownKeys: target => Object.keys(target.__fields),
-            getOwnPropertyDescriptor: (target, prop) => {
-                if (prop in target.__fields) {
-                    return {
-                        configurable: true,//TODO Should configurable be true?
-                        enumerable: true,
-                    };
-                }
-                return Reflect.getOwnPropertyDescriptor(target, prop);
-            },
-            deleteProperty: deleteProperty,
-            defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); },
-        });
-        this[SelfProxy] = list;
-        if (fields) {
-            (list as any).push(...fields);
-        }
-        return list;
-    }
-
-    [key: number]: T | (T extends RefField ? Promise<T> : never);
-
-    // this requests all ProxyFields at the same time to avoid the overhead
-    // of separate network requests and separate updates to the React dom.
-    private __realFields() {
-        const waiting = this.__fields.filter(f => f instanceof ProxyField && f.promisedValue());
-        const promised = waiting.map(f => f instanceof ProxyField ? f.promisedValue() : "");
-        // if we find any ProxyFields that don't have a current value, then
-        // start the server request for all of them
-        if (promised.length) {
-            const promise = DocServer.GetRefFields(promised);
-            // as soon as we get the fields from the server, set all the list values in one
-            // action to generate one React dom update.
-            promise.then(fields => runInAction(() => {
-                waiting.map((w, i) => w instanceof ProxyField && w.setValue(fields[promised[i]]));
-            }));
-            // we also have to mark all lists items with this promise so that any calls to them
-            // will await the batch request.
-            // This counts on the handler for 'promise' in the call above being invoked before the
-            // handler for 'promise' in the lines below.
-            waiting.map((w, i) => {
-                w instanceof ProxyField && w.setPromise(promise.then(fields => fields[promised[i]]));
-            });
-        }
-        return this.__fields.map(toRealField);
-    }
-
-    @serializable(alias("fields", list(autoObject(), { afterDeserialize: afterDocDeserialize })))
-    private get __fields() {
-        return this.___fields;
-    }
-
-    private set __fields(value) {
-        this.___fields = value;
-        for (const key in value) {
-            const field = value[key];
-            if (!(field instanceof ObjectField)) continue;
-            (field as ObjectField)[Parent] = this[Self];
-            (field as ObjectField)[OnUpdate] = updateFunction(this[Self], key, field, this[SelfProxy]);
-        }
-    }
-
-    [Copy]() {
-        const copiedData = this[Self].__fields.map(f => f instanceof ObjectField ? f[Copy]() : f);
-        const deepCopy = new ListImpl<T>(copiedData as any);
-        return deepCopy;
-    }
-
-    // @serializable(alias("fields", list(autoObject())))
-    @observable
-    private ___fields: StoredType<T>[] = [];
-
-    private [Update] = (diff: any) => {
-        // console.log(diff);
-        const update = this[OnUpdate];
-        // update && update(diff);
-        update?.();
-    }
-
-    private [Self] = this;
-    private [SelfProxy]: any;
-
-    [ToScriptString]() {
-        return `new List([${(this as any).map((field: any) => Field.toScriptString(field))}])`;
-    }
-    [ToString]() {
-        return "List";
-    }
-}
-export type List<T extends Field> = ListImpl<T> & (T | (T extends RefField ? Promise<T> : never))[];
-export const List: { new <T extends Field>(fields?: T[]): List<T> } = ListImpl as any;
-
-Scripting.addGlobal("List", List);
\ No newline at end of file
diff --git a/src/new_fields/ListSpec.ts b/src/new_fields/ListSpec.ts
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/new_fields/ObjectField.ts b/src/new_fields/ObjectField.ts
deleted file mode 100644
index 9aa1c9b04..000000000
--- a/src/new_fields/ObjectField.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { RefField } from "./RefField";
-import { OnUpdate, Parent, Copy, ToScriptString, ToString } from "./FieldSymbols";
-import { Scripting } from "../client/util/Scripting";
-
-export abstract class ObjectField {
-    protected [OnUpdate](diff?: any) { }
-    private [Parent]?: RefField | ObjectField;
-    abstract [Copy](): ObjectField;
-
-    abstract [ToScriptString](): string;
-    abstract [ToString](): string;
-}
-
-export namespace ObjectField {
-    export function MakeCopy<T extends ObjectField>(field: T) {
-        return field?.[Copy]();
-    }
-}
-
-Scripting.addGlobal(ObjectField);
\ No newline at end of file
diff --git a/src/new_fields/PresField.ts b/src/new_fields/PresField.ts
deleted file mode 100644
index f236a04fd..000000000
--- a/src/new_fields/PresField.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-//insert code here
-import { ObjectField } from "./ObjectField";
-
-export abstract class PresField extends ObjectField {
-
-}
\ No newline at end of file
diff --git a/src/new_fields/Proxy.ts b/src/new_fields/Proxy.ts
deleted file mode 100644
index 555faaad0..000000000
--- a/src/new_fields/Proxy.ts
+++ /dev/null
@@ -1,126 +0,0 @@
-import { Deserializable } from "../client/util/SerializationHelper";
-import { FieldWaiting } from "./Doc";
-import { primitive, serializable } from "serializr";
-import { observable, action, runInAction } from "mobx";
-import { DocServer } from "../client/DocServer";
-import { RefField } from "./RefField";
-import { ObjectField } from "./ObjectField";
-import { Id, Copy, ToScriptString, ToString } from "./FieldSymbols";
-import { scriptingGlobal } from "../client/util/Scripting";
-import { Plugins } from "./util";
-
-@Deserializable("proxy")
-export class ProxyField<T extends RefField> extends ObjectField {
-    constructor();
-    constructor(value: T);
-    constructor(fieldId: string);
-    constructor(value?: T | string) {
-        super();
-        if (typeof value === "string") {
-            this.fieldId = value;
-        } else if (value) {
-            this.cache = value;
-            this.fieldId = value[Id];
-        }
-    }
-
-    [Copy]() {
-        if (this.cache) return new ProxyField<T>(this.cache);
-        return new ProxyField<T>(this.fieldId);
-    }
-
-    [ToScriptString]() {
-        return "invalid";
-    }
-    [ToString]() {
-        return "ProxyField";
-    }
-
-    @serializable(primitive())
-    readonly fieldId: string = "";
-
-    // This getter/setter and nested object thing is 
-    // because mobx doesn't play well with observable proxies
-    @observable.ref
-    private _cache: { readonly field: T | undefined } = { field: undefined };
-    private get cache(): T | undefined {
-        return this._cache.field;
-    }
-    private set cache(field: T | undefined) {
-        this._cache = { field };
-    }
-
-    private failed = false;
-    private promise?: Promise<any>;
-
-    value(): T | undefined | FieldWaiting<T> {
-        if (this.cache) {
-            return this.cache;
-        }
-        if (this.failed) {
-            return undefined;
-        }
-        if (!this.promise) {
-            const cached = DocServer.GetCachedRefField(this.fieldId);
-            if (cached !== undefined) {
-                runInAction(() => this.cache = cached as any);
-                return cached as any;
-            }
-            this.promise = DocServer.GetRefField(this.fieldId).then(action((field: any) => {
-                this.promise = undefined;
-                this.cache = field;
-                if (field === undefined) this.failed = true;
-                return field;
-            }));
-        }
-        return this.promise as any;
-    }
-    promisedValue(): string { return !this.cache && !this.failed && !this.promise ? this.fieldId : ""; }
-    setPromise(promise: any) {
-        this.promise = promise;
-    }
-    @action
-    setValue(field: any) {
-        this.promise = undefined;
-        this.cache = field;
-        if (field === undefined) this.failed = true;
-        return field;
-    }
-}
-
-export namespace ProxyField {
-    let useProxy = true;
-    export function DisableProxyFields() {
-        useProxy = false;
-    }
-
-    export function EnableProxyFields() {
-        useProxy = true;
-    }
-
-    export function WithoutProxy<T>(fn: () => T) {
-        DisableProxyFields();
-        try {
-            return fn();
-        } finally {
-            EnableProxyFields();
-        }
-    }
-
-    export function initPlugin() {
-        Plugins.addGetterPlugin((doc, _, value) => {
-            if (useProxy && value instanceof ProxyField) {
-                return { value: value.value() };
-            }
-        });
-    }
-}
-
-function prefetchValue(proxy: PrefetchProxy<RefField>) {
-    return proxy.value() as any;
-}
-
-@scriptingGlobal
-@Deserializable("prefetch_proxy", prefetchValue)
-export class PrefetchProxy<T extends RefField> extends ProxyField<T> {
-}
diff --git a/src/new_fields/RefField.ts b/src/new_fields/RefField.ts
deleted file mode 100644
index b6ef69750..000000000
--- a/src/new_fields/RefField.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { serializable, primitive, alias } from "serializr";
-import { Utils } from "../Utils";
-import { Id, HandleUpdate, ToScriptString, ToString } from "./FieldSymbols";
-import { afterDocDeserialize } from "../client/util/SerializationHelper";
-
-export type FieldId = string;
-export abstract class RefField {
-    @serializable(alias("id", primitive({ afterDeserialize: afterDocDeserialize })))
-    private __id: FieldId;
-    readonly [Id]: FieldId;
-
-    constructor(id?: FieldId) {
-        this.__id = id || Utils.GenerateGuid();
-        this[Id] = this.__id;
-    }
-
-    protected [HandleUpdate]?(diff: any): void | Promise<void>;
-
-    abstract [ToScriptString](): string;
-    abstract [ToString](): string;
-}
diff --git a/src/new_fields/RichTextField.ts b/src/new_fields/RichTextField.ts
deleted file mode 100644
index 5cf0e0cc3..000000000
--- a/src/new_fields/RichTextField.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { ObjectField } from "./ObjectField";
-import { serializable } from "serializr";
-import { Deserializable } from "../client/util/SerializationHelper";
-import { Copy, ToScriptString, ToPlainText, ToString } from "./FieldSymbols";
-import { scriptingGlobal } from "../client/util/Scripting";
-
-@scriptingGlobal
-@Deserializable("RichTextField")
-export class RichTextField extends ObjectField {
-    @serializable(true)
-    readonly Data: string;
-
-    @serializable(true)
-    readonly Text: string;
-
-    constructor(data: string, text: string = "") {
-        super();
-        this.Data = data;
-        this.Text = text;
-    }
-
-    Empty() {
-        return !(this.Text || this.Data.toString().includes("dashField"));
-    }
-
-    [Copy]() {
-        return new RichTextField(this.Data, this.Text);
-    }
-
-    [ToScriptString]() {
-        return `new RichTextField("${this.Data}", "${this.Text}")`;
-    }
-    [ToString]() {
-        return this.Text;
-    }
-
-    public static DashField(fieldKey: string) {
-        return new RichTextField(`{"doc":{"type":"doc","content":[{"type":"paragraph","attrs":{"align":null,"color":null,"id":null,"indent":null,"inset":null,"lineSpacing":null,"paddingBottom":null,"paddingTop":null},"content":[{"type":"dashField","attrs":{"fieldKey":"${fieldKey}","docid":""}}]}]},"selection":{"type":"text","anchor":2,"head":2},"storedMarks":[]}`, "");
-    }
-
-}
\ No newline at end of file
diff --git a/src/new_fields/RichTextUtils.ts b/src/new_fields/RichTextUtils.ts
deleted file mode 100644
index c475d0d73..000000000
--- a/src/new_fields/RichTextUtils.ts
+++ /dev/null
@@ -1,519 +0,0 @@
-import { AssertionError } from "assert";
-import { docs_v1 } from "googleapis";
-import { Fragment, Mark, Node } from "prosemirror-model";
-import { sinkListItem } from "prosemirror-schema-list";
-import { Utils } from "../Utils";
-import { Docs } from "../client/documents/Documents";
-import { schema } from "../client/views/nodes/formattedText/schema_rts";
-import { GooglePhotos } from "../client/apis/google_docs/GooglePhotosClientUtils";
-import { DocServer } from "../client/DocServer";
-import { Networking } from "../client/Network";
-import { FormattedTextBox } from "../client/views/nodes/formattedText/FormattedTextBox";
-import { Doc, Opt } from "./Doc";
-import { Id } from "./FieldSymbols";
-import { RichTextField } from "./RichTextField";
-import { Cast, StrCast } from "./Types";
-import Color = require('color');
-import { EditorState, TextSelection, Transaction } from "prosemirror-state";
-import { GoogleApiClientUtils } from "../client/apis/google_docs/GoogleApiClientUtils";
-
-export namespace RichTextUtils {
-
-    const delimiter = "\n";
-    const joiner = "";
-
-
-    export const Initialize = (initial?: string) => {
-        const content: any[] = [];
-        const state = {
-            doc: {
-                type: "doc",
-                content,
-            },
-            selection: {
-                type: "text",
-                anchor: 0,
-                head: 0
-            }
-        };
-        if (initial && initial.length) {
-            content.push({
-                type: "paragraph",
-                content: {
-                    type: "text",
-                    text: initial
-                }
-            });
-            state.selection.anchor = state.selection.head = initial.length + 1;
-        }
-        return JSON.stringify(state);
-    };
-
-    export const Synthesize = (plainText: string, oldState?: RichTextField) => {
-        return new RichTextField(ToProsemirrorState(plainText, oldState), plainText);
-    };
-
-    export const ToPlainText = (state: EditorState) => {
-        // Because we're working with plain text, just concatenate all paragraphs
-        const content = state.doc.content;
-        const paragraphs: Node<any>[] = [];
-        content.forEach(node => node.type.name === "paragraph" && paragraphs.push(node));
-
-        // Functions to flatten ProseMirror paragraph objects (and their components) to plain text
-        // Concatentate paragraphs and string the result together
-        const textParagraphs: string[] = paragraphs.map(paragraph => {
-            const text: string[] = [];
-            paragraph.content.forEach(node => node.text && text.push(node.text));
-            return text.join(joiner) + delimiter;
-        });
-        const plainText = textParagraphs.join(joiner);
-        return plainText.substring(0, plainText.length - 1);
-    };
-
-    export const ToProsemirrorState = (plainText: string, oldState?: RichTextField) => {
-        // Remap the text, creating blocks split on newlines
-        const elements = plainText.split(delimiter);
-
-        // Google Docs adds in an extra carriage return automatically, so this counteracts it
-        !elements[elements.length - 1].length && elements.pop();
-
-        // Preserve the current state, but re-write the content to be the blocks
-        const parsed = JSON.parse(oldState ? oldState.Data : Initialize());
-        parsed.doc.content = elements.map(text => {
-            const paragraph: any = { type: "paragraph" };
-            text.length && (paragraph.content = [{ type: "text", marks: [], text }]); // An empty paragraph gets treated as a line break
-            return paragraph;
-        });
-
-        // If the new content is shorter than the previous content and selection is unchanged, may throw an out of bounds exception, so we reset it
-        parsed.selection = { type: "text", anchor: 1, head: 1 };
-
-        // Export the ProseMirror-compatible state object we've just built
-        return JSON.stringify(parsed);
-    };
-
-    export namespace GoogleDocs {
-
-        export const Export = async (state: EditorState): Promise<GoogleApiClientUtils.Docs.Content> => {
-            const nodes: (Node<any> | null)[] = [];
-            const text = ToPlainText(state);
-            state.doc.content.forEach(node => {
-                if (!node.childCount) {
-                    nodes.push(null);
-                } else {
-                    node.content.forEach(child => nodes.push(child));
-                }
-            });
-            const requests = await marksToStyle(nodes);
-            return { text, requests };
-        };
-
-        interface ImageTemplate {
-            width: number;
-            title: string;
-            url: string;
-            agnostic: string;
-        }
-
-        const parseInlineObjects = async (document: docs_v1.Schema$Document): Promise<Map<string, ImageTemplate>> => {
-            const inlineObjectMap = new Map<string, ImageTemplate>();
-            const inlineObjects = document.inlineObjects;
-
-            if (inlineObjects) {
-                const objects = Object.keys(inlineObjects).map(objectId => inlineObjects[objectId]);
-                const mediaItems: MediaItem[] = objects.map(object => {
-                    const embeddedObject = object.inlineObjectProperties!.embeddedObject!;
-                    return { baseUrl: embeddedObject.imageProperties!.contentUri! };
-                });
-
-                const uploads = await Networking.PostToServer("/googlePhotosMediaGet", { mediaItems });
-
-                if (uploads.length !== mediaItems.length) {
-                    throw new AssertionError({ expected: mediaItems.length, actual: uploads.length, message: "Error with internally uploading inlineObjects!" });
-                }
-
-                for (let i = 0; i < objects.length; i++) {
-                    const object = objects[i];
-                    const { accessPaths } = uploads[i];
-                    const { agnostic, _m } = accessPaths;
-                    const embeddedObject = object.inlineObjectProperties!.embeddedObject!;
-                    const size = embeddedObject.size!;
-                    const width = size.width!.magnitude!;
-
-                    inlineObjectMap.set(object.objectId!, {
-                        title: embeddedObject.title || `Imported Image from ${document.title}`,
-                        width,
-                        url: Utils.prepend(_m.client),
-                        agnostic: Utils.prepend(agnostic.client)
-                    });
-                }
-            }
-            return inlineObjectMap;
-        };
-
-        type BulletPosition = { value: number, sinks: number };
-
-        interface MediaItem {
-            baseUrl: string;
-        }
-
-        export const Import = async (documentId: GoogleApiClientUtils.Docs.DocumentId, textNote: Doc): Promise<Opt<GoogleApiClientUtils.Docs.ImportResult>> => {
-            const document = await GoogleApiClientUtils.Docs.retrieve({ documentId });
-            if (!document) {
-                return undefined;
-            }
-            const inlineObjectMap = await parseInlineObjects(document);
-            const title = document.title!;
-            const { text, paragraphs } = GoogleApiClientUtils.Docs.Utils.extractText(document);
-            let state = FormattedTextBox.blankState();
-            const structured = parseLists(paragraphs);
-
-            let position = 3;
-            const lists: ListGroup[] = [];
-            const indentMap = new Map<ListGroup, BulletPosition[]>();
-            let globalOffset = 0;
-            const nodes: Node<any>[] = [];
-            for (const element of structured) {
-                if (Array.isArray(element)) {
-                    lists.push(element);
-                    const positions: BulletPosition[] = [];
-                    const items = element.map(paragraph => {
-                        const item = listItem(state.schema, paragraph.contents);
-                        const sinks = paragraph.bullet!;
-                        positions.push({
-                            value: position + globalOffset,
-                            sinks
-                        });
-                        position += item.nodeSize;
-                        globalOffset += 2 * sinks;
-                        return item;
-                    });
-                    indentMap.set(element, positions);
-                    nodes.push(list(state.schema, items));
-                } else {
-                    if (element.contents.some(child => "inlineObjectId" in child)) {
-                        const group = element.contents;
-                        group.forEach((child, i) => {
-                            let node: Opt<Node<any>>;
-                            if ("inlineObjectId" in child) {
-                                node = imageNode(state.schema, inlineObjectMap.get(child.inlineObjectId!)!, textNote);
-                            } else if ("content" in child && (i !== group.length - 1 || child.content!.removeTrailingNewlines().length)) {
-                                node = paragraphNode(state.schema, [child]);
-                            }
-                            if (node) {
-                                position += node.nodeSize;
-                                nodes.push(node);
-                            }
-                        });
-                    } else {
-                        const paragraph = paragraphNode(state.schema, element.contents);
-                        nodes.push(paragraph);
-                        position += paragraph.nodeSize;
-                    }
-                }
-            }
-            state = state.apply(state.tr.replaceWith(0, 2, nodes));
-
-            const sink = sinkListItem(state.schema.nodes.list_item);
-            const dispatcher = (tr: Transaction) => state = state.apply(tr);
-            for (const list of lists) {
-                for (const pos of indentMap.get(list)!) {
-                    const resolved = state.doc.resolve(pos.value);
-                    state = state.apply(state.tr.setSelection(new TextSelection(resolved)));
-                    for (let i = 0; i < pos.sinks; i++) {
-                        sink(state, dispatcher);
-                    }
-                }
-            }
-
-            return { title, text, state };
-        };
-
-        type Paragraph = GoogleApiClientUtils.Docs.Utils.DeconstructedParagraph;
-        type ListGroup = Paragraph[];
-        type PreparedParagraphs = (ListGroup | Paragraph)[];
-
-        const parseLists = (paragraphs: ListGroup) => {
-            const groups: PreparedParagraphs = [];
-            let group: ListGroup = [];
-            for (const paragraph of paragraphs) {
-                if (paragraph.bullet !== undefined) {
-                    group.push(paragraph);
-                } else {
-                    if (group.length) {
-                        groups.push(group);
-                        group = [];
-                    }
-                    groups.push(paragraph);
-                }
-            }
-            group.length && groups.push(group);
-            return groups;
-        };
-
-        const listItem = (schema: any, runs: docs_v1.Schema$TextRun[]): Node => {
-            return schema.node("list_item", null, paragraphNode(schema, runs));
-        };
-
-        const list = (schema: any, items: Node[]): Node => {
-            return schema.node("bullet_list", null, items);
-        };
-
-        const paragraphNode = (schema: any, runs: docs_v1.Schema$TextRun[]): Node => {
-            const children = runs.map(run => textNode(schema, run)).filter(child => child !== undefined);
-            const fragment = children.length ? Fragment.from(children) : undefined;
-            return schema.node("paragraph", null, fragment);
-        };
-
-        const imageNode = (schema: any, image: ImageTemplate, textNote: Doc) => {
-            const { url: src, width, agnostic } = image;
-            let docid: string;
-            const guid = Utils.GenerateDeterministicGuid(agnostic);
-            const backingDocId = StrCast(textNote[guid]);
-            if (!backingDocId) {
-                const backingDoc = Docs.Create.ImageDocument(agnostic, { _width: 300, _height: 300 });
-                Doc.makeCustomViewClicked(backingDoc, Docs.Create.FreeformDocument);
-                docid = backingDoc[Id];
-                textNote[guid] = docid;
-            } else {
-                docid = backingDocId;
-            }
-            return schema.node("image", { src, agnostic, width, docid, float: null, location: "onRight" });
-        };
-
-        const textNode = (schema: any, run: docs_v1.Schema$TextRun) => {
-            const text = run.content!.removeTrailingNewlines();
-            return text.length ? schema.text(text, styleToMarks(schema, run.textStyle)) : undefined;
-        };
-
-        const StyleToMark = new Map<keyof docs_v1.Schema$TextStyle, keyof typeof schema.marks>([
-            ["bold", "strong"],
-            ["italic", "em"],
-            ["foregroundColor", "pFontColor"],
-            ["fontSize", "pFontSize"]
-        ]);
-
-        const styleToMarks = (schema: any, textStyle?: docs_v1.Schema$TextStyle) => {
-            if (!textStyle) {
-                return undefined;
-            }
-            const marks: Mark[] = [];
-            Object.keys(textStyle).forEach(key => {
-                let value: any;
-                const targeted = key as keyof docs_v1.Schema$TextStyle;
-                if (value = textStyle[targeted]) {
-                    const attributes: any = {};
-                    let converted = StyleToMark.get(targeted) || targeted;
-
-                    value.url && (attributes.href = value.url);
-                    if (value.color) {
-                        const object = value.color.rgbColor;
-                        attributes.color = Color.rgb(["red", "green", "blue"].map(color => object[color] * 255 || 0)).hex();
-                    }
-                    if (value.magnitude) {
-                        attributes.fontSize = value.magnitude;
-                    }
-
-                    if (converted === "weightedFontFamily") {
-                        converted = ImportFontFamilyMapping.get(value.fontFamily) || "timesNewRoman";
-                    }
-
-                    const mapped = schema.marks[converted];
-                    if (!mapped) {
-                        alert(`No mapping found for ${converted}!`);
-                        return;
-                    }
-
-                    const mark = schema.mark(mapped, attributes);
-                    mark && marks.push(mark);
-                }
-            });
-            return marks;
-        };
-
-        const MarkToStyle = new Map<keyof typeof schema.marks, keyof docs_v1.Schema$TextStyle>([
-            ["strong", "bold"],
-            ["em", "italic"],
-            ["pFontColor", "foregroundColor"],
-            ["pFontSize", "fontSize"],
-            ["timesNewRoman", "weightedFontFamily"],
-            ["georgia", "weightedFontFamily"],
-            ["comicSans", "weightedFontFamily"],
-            ["tahoma", "weightedFontFamily"],
-            ["impact", "weightedFontFamily"]
-        ]);
-
-        const ExportFontFamilyMapping = new Map<string, string>([
-            ["timesNewRoman", "Times New Roman"],
-            ["arial", "Arial"],
-            ["georgia", "Georgia"],
-            ["comicSans", "Comic Sans MS"],
-            ["tahoma", "Tahoma"],
-            ["impact", "Impact"]
-        ]);
-
-        const ImportFontFamilyMapping = new Map<string, string>([
-            ["Times New Roman", "timesNewRoman"],
-            ["Arial", "arial"],
-            ["Georgia", "georgia"],
-            ["Comic Sans MS", "comicSans"],
-            ["Tahoma", "tahoma"],
-            ["Impact", "impact"]
-        ]);
-
-        const ignored = ["user_mark"];
-
-        const marksToStyle = async (nodes: (Node<any> | null)[]): Promise<docs_v1.Schema$Request[]> => {
-            const requests: docs_v1.Schema$Request[] = [];
-            let position = 1;
-            for (const node of nodes) {
-                if (node === null) {
-                    position += 2;
-                    continue;
-                }
-                const { marks, attrs, nodeSize } = node;
-                const textStyle: docs_v1.Schema$TextStyle = {};
-                const information: LinkInformation = {
-                    startIndex: position,
-                    endIndex: position + nodeSize,
-                    textStyle
-                };
-                let mark: Mark<any>;
-                const markMap = BuildMarkMap(marks);
-                for (const markName of Object.keys(schema.marks)) {
-                    if (ignored.includes(markName) || !(mark = markMap[markName])) {
-                        continue;
-                    }
-                    let converted = MarkToStyle.get(markName) || markName as keyof docs_v1.Schema$TextStyle;
-                    let value: any = true;
-                    if (!converted) {
-                        continue;
-                    }
-                    const { attrs } = mark;
-                    switch (converted) {
-                        case "link":
-                            let url = attrs.href;
-                            const delimiter = "/doc/";
-                            const alreadyShared = "?sharing=true";
-                            if (new RegExp(window.location.origin + delimiter).test(url) && !url.endsWith(alreadyShared)) {
-                                const linkDoc = await DocServer.GetRefField(url.split(delimiter)[1]);
-                                if (linkDoc instanceof Doc) {
-                                    let exported = (await Cast(linkDoc.anchor2, Doc))!;
-                                    if (!exported.customLayout) {
-                                        exported = Doc.MakeAlias(exported);
-                                        Doc.makeCustomViewClicked(exported, Docs.Create.FreeformDocument);
-                                        linkDoc.anchor2 = exported;
-                                    }
-                                    url = Utils.shareUrl(exported[Id]);
-                                }
-                            }
-                            value = { url };
-                            textStyle.foregroundColor = fromRgb.blue;
-                            textStyle.bold = true;
-                            break;
-                        case "fontSize":
-                            value = { magnitude: attrs.fontSize, unit: "PT" };
-                            break;
-                        case "foregroundColor":
-                            value = fromHex(attrs.color);
-                            break;
-                        case "weightedFontFamily":
-                            value = { fontFamily: ExportFontFamilyMapping.get(markName) };
-                    }
-                    let matches: RegExpExecArray | null;
-                    if ((matches = /p(\d+)/g.exec(markName)) !== null) {
-                        converted = "fontSize";
-                        value = { magnitude: parseInt(matches[1].replace("px", "")), unit: "PT" };
-                    }
-                    textStyle[converted] = value;
-                }
-                if (Object.keys(textStyle).length) {
-                    requests.push(EncodeStyleUpdate(information));
-                }
-                if (node.type.name === "image") {
-                    const width = attrs.width;
-                    requests.push(await EncodeImage({
-                        startIndex: position + nodeSize - 1,
-                        uri: attrs.agnostic,
-                        width: Number(typeof width === "string" ? width.replace("px", "") : width)
-                    }));
-                }
-                position += nodeSize;
-            }
-            return requests;
-        };
-
-        const BuildMarkMap = (marks: Mark<any>[]) => {
-            const markMap: { [type: string]: Mark<any> } = {};
-            marks.forEach(mark => markMap[mark.type.name] = mark);
-            return markMap;
-        };
-
-        interface LinkInformation {
-            startIndex: number;
-            endIndex: number;
-            textStyle: docs_v1.Schema$TextStyle;
-        }
-
-        interface ImageInformation {
-            startIndex: number;
-            width: number;
-            uri: string;
-        }
-
-        namespace fromRgb {
-
-            export const convert = (red: number, green: number, blue: number): docs_v1.Schema$OptionalColor => {
-                return {
-                    color: {
-                        rgbColor: {
-                            red: red / 255,
-                            green: green / 255,
-                            blue: blue / 255
-                        }
-                    }
-                };
-            };
-
-            export const red = convert(255, 0, 0);
-            export const green = convert(0, 255, 0);
-            export const blue = convert(0, 0, 255);
-
-        }
-
-        const fromHex = (color: string): docs_v1.Schema$OptionalColor => {
-            const c = Color(color);
-            return fromRgb.convert(c.red(), c.green(), c.blue());
-        };
-
-        const EncodeStyleUpdate = (information: LinkInformation): docs_v1.Schema$Request => {
-            const { startIndex, endIndex, textStyle } = information;
-            return {
-                updateTextStyle: {
-                    fields: "*",
-                    range: { startIndex, endIndex },
-                    textStyle
-                } as docs_v1.Schema$UpdateTextStyleRequest
-            };
-        };
-
-        const EncodeImage = async ({ uri, width, startIndex }: ImageInformation) => {
-            if (!uri) {
-                return {};
-            }
-            const source = [Docs.Create.ImageDocument(uri)];
-            const baseUrls = await GooglePhotos.Transactions.UploadThenFetch(source);
-            if (baseUrls) {
-                return {
-                    insertInlineImage: {
-                        uri: baseUrls[0],
-                        objectSize: { width: { magnitude: width, unit: "PT" } },
-                        location: { index: startIndex }
-                    }
-                };
-            }
-            return {};
-        };
-    }
-
-}
\ No newline at end of file
diff --git a/src/new_fields/Schema.ts b/src/new_fields/Schema.ts
deleted file mode 100644
index 72bce283d..000000000
--- a/src/new_fields/Schema.ts
+++ /dev/null
@@ -1,120 +0,0 @@
-import { Interface, ToInterface, Cast, ToConstructor, HasTail, Head, Tail, ListSpec, ToType, DefaultFieldConstructor } from "./Types";
-import { Doc, Field } from "./Doc";
-import { ObjectField } from "./ObjectField";
-import { RefField } from "./RefField";
-import { SelfProxy } from "./FieldSymbols";
-
-type AllToInterface<T extends Interface[]> = {
-    1: ToInterface<Head<T>> & AllToInterface<Tail<T>>,
-    0: ToInterface<Head<T>>
-}[HasTail<T> extends true ? 1 : 0];
-
-export const emptySchema = createSchema({});
-export const Document = makeInterface(emptySchema);
-export type Document = makeInterface<[typeof emptySchema]>;
-
-export interface InterfaceFunc<T extends Interface[]> {
-    (docs: Doc[]): makeInterface<T>[];
-    (): makeInterface<T>;
-    (doc: Doc): makeInterface<T>;
-}
-
-export type makeInterface<T extends Interface[]> = AllToInterface<T> & Doc & { proto: Doc | undefined };
-// export function makeInterface<T extends Interface[], U extends Doc>(schemas: T): (doc: U) => All<T, U>;
-// export function makeInterface<T extends Interface, U extends Doc>(schema: T): (doc: U) => makeInterface<T, U>; 
-export function makeInterface<T extends Interface[]>(...schemas: T): InterfaceFunc<T> {
-    const schema: Interface = {};
-    for (const s of schemas) {
-        for (const key in s) {
-            schema[key] = s[key];
-        }
-    }
-    const proto = new Proxy({}, {
-        get(target: any, prop, receiver) {
-            const field = receiver.doc[prop];
-            if (prop in schema) {
-                const desc = prop === "proto" ? Doc : (schema as any)[prop]; // bcz: proto doesn't appear in schemas ... maybe it should?
-                if (typeof desc === "object" && "defaultVal" in desc && "type" in desc) {//defaultSpec
-                    return Cast(field, desc.type, desc.defaultVal);
-                } else if (typeof desc === "function" && !ObjectField.isPrototypeOf(desc) && !RefField.isPrototypeOf(desc)) {
-                    const doc = Cast(field, Doc);
-                    if (doc === undefined) {
-                        return undefined;
-                    } else if (doc instanceof Doc) {
-                        return desc(doc);
-                    } else {
-                        return doc.then(doc => doc && desc(doc));
-                    }
-                } else {
-                    return Cast(field, desc);
-                }
-            }
-            return field;
-        },
-        set(target: any, prop, value, receiver) {
-            receiver.doc[prop] = value;
-            return true;
-        }
-    });
-    const fn = (doc: Doc) => {
-        doc = doc[SelfProxy];
-        // if (!(doc instanceof Doc)) {
-        //     throw new Error("Currently wrapping a schema in another schema isn't supported");
-        // }
-        const obj = Object.create(proto, { doc: { value: doc, writable: false } });
-        return obj;
-    };
-    return function (doc?: Doc | Doc[]) {
-        doc = doc || new Doc;
-        if (doc instanceof Doc) {
-            return fn(doc);
-        } else {
-            return doc.map(fn);
-        }
-    };
-}
-
-export type makeStrictInterface<T extends Interface> = Partial<ToInterface<T>>;
-export function makeStrictInterface<T extends Interface>(schema: T): (doc: Doc) => makeStrictInterface<T> {
-    const proto = {};
-    for (const key in schema) {
-        const type = schema[key];
-        Object.defineProperty(proto, key, {
-            get() {
-                return Cast(this.__doc[key], type as any);
-            },
-            set(value) {
-                value = Cast(value, type as any);
-                if (value !== undefined) {
-                    this.__doc[key] = value;
-                    return;
-                }
-                throw new TypeError("Expected type " + type);
-            }
-        });
-    }
-    return function (doc: any) {
-        if (!(doc instanceof Doc)) {
-            throw new Error("Currently wrapping a schema in another schema isn't supported");
-        }
-        const obj = Object.create(proto);
-        obj.__doc = doc;
-        return obj;
-    };
-}
-
-export function createSchema<T extends Interface>(schema: T): T & { proto: ToConstructor<Doc> } {
-    (schema as any).proto = Doc;
-    return schema as any;
-}
-
-export function listSpec<U extends ToConstructor<Field>>(type: U): ListSpec<ToType<U>> {
-    return { List: type as any };//TODO Types
-}
-
-export function defaultSpec<T extends ToConstructor<Field>>(type: T, defaultVal: ToType<T>): DefaultFieldConstructor<ToType<T>> {
-    return {
-        type: type as any,
-        defaultVal
-    };
-}
\ No newline at end of file
diff --git a/src/new_fields/SchemaHeaderField.ts b/src/new_fields/SchemaHeaderField.ts
deleted file mode 100644
index 07c90f5a2..000000000
--- a/src/new_fields/SchemaHeaderField.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-import { Deserializable } from "../client/util/SerializationHelper";
-import { serializable, primitive } from "serializr";
-import { ObjectField } from "./ObjectField";
-import { Copy, ToScriptString, ToString, OnUpdate } from "./FieldSymbols";
-import { scriptingGlobal } from "../client/util/Scripting";
-import { ColumnType } from "../client/views/collections/CollectionSchemaView";
-
-export const PastelSchemaPalette = new Map<string, string>([
-    // ["pink1", "#FFB4E8"],
-    ["pink2", "#ff9cee"],
-    ["pink3", "#ffccf9"],
-    ["pink4", "#fcc2ff"],
-    ["pink5", "#f6a6ff"],
-    ["purple1", "#b28dff"],
-    ["purple2", "#c5a3ff"],
-    ["purple3", "#d5aaff"],
-    ["purple4", "#ecd4ff"],
-    // ["purple5", "#fb34ff"],
-    ["purple6", "#dcd3ff"],
-    ["purple7", "#a79aff"],
-    ["purple8", "#b5b9ff"],
-    ["purple9", "#97a2ff"],
-    ["bluegreen1", "#afcbff"],
-    ["bluegreen2", "#aff8db"],
-    ["bluegreen3", "#c4faf8"],
-    ["bluegreen4", "#85e3ff"],
-    ["bluegreen5", "#ace7ff"],
-    // ["bluegreen6", "#6eb5ff"],
-    ["bluegreen7", "#bffcc6"],
-    ["bluegreen8", "#dbffd6"],
-    ["yellow1", "#f3ffe3"],
-    ["yellow2", "#e7ffac"],
-    ["yellow3", "#ffffd1"],
-    ["yellow4", "#fff5ba"],
-    // ["red1", "#ffc9de"],
-    ["red2", "#ffabab"],
-    ["red3", "#ffbebc"],
-    ["red4", "#ffcbc1"],
-    ["orange1", "#ffd5b3"],
-]);
-
-export const RandomPastel = () => Array.from(PastelSchemaPalette.values())[Math.floor(Math.random() * PastelSchemaPalette.size)];
-
-export const DarkPastelSchemaPalette = new Map<string, string>([
-    ["pink2", "#c932b0"],
-    ["purple4", "#913ad6"],
-    ["bluegreen1", "#3978ed"],
-    ["bluegreen7", "#2adb3e"],
-    ["bluegreen5", "#21b0eb"],
-    ["yellow4", "#edcc0c"],
-    ["red2", "#eb3636"],
-    ["orange1", "#f2740f"],
-]);
-
-@scriptingGlobal
-@Deserializable("schemaheader")
-export class SchemaHeaderField extends ObjectField {
-    @serializable(primitive())
-    heading: string;
-    @serializable(primitive())
-    color: string;
-    @serializable(primitive())
-    type: number;
-    @serializable(primitive())
-    width: number;
-    @serializable(primitive())
-    collapsed: boolean | undefined;
-    @serializable(primitive())
-    desc: boolean | undefined; // boolean determines sort order, undefined when no sort
-
-    constructor(heading: string = "", color: string = RandomPastel(), type?: ColumnType, width?: number, desc?: boolean, collapsed?: boolean) {
-        super();
-
-        this.heading = heading;
-        this.color = color;
-        this.type = type ? type : 0;
-        this.width = width ? width : -1;
-        this.desc = desc;
-        this.collapsed = collapsed;
-    }
-
-    setHeading(heading: string) {
-        this.heading = heading;
-        this[OnUpdate]();
-    }
-
-    setColor(color: string) {
-        this.color = color;
-        this[OnUpdate]();
-    }
-
-    setType(type: ColumnType) {
-        this.type = type;
-        this[OnUpdate]();
-    }
-
-    setWidth(width: number) {
-        this.width = width;
-        this[OnUpdate]();
-    }
-
-    setDesc(desc: boolean | undefined) {
-        this.desc = desc;
-        this[OnUpdate]();
-    }
-
-    setCollapsed(collapsed: boolean | undefined) {
-        this.collapsed = collapsed;
-        this[OnUpdate]();
-    }
-
-    [Copy]() {
-        return new SchemaHeaderField(this.heading, this.color, this.type);
-    }
-
-    [ToScriptString]() {
-        return `invalid`;
-    }
-    [ToString]() {
-        return `SchemaHeaderField`;
-    }
-}
\ No newline at end of file
diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts
deleted file mode 100644
index 4b790f483..000000000
--- a/src/new_fields/ScriptField.ts
+++ /dev/null
@@ -1,193 +0,0 @@
-import { ObjectField } from "./ObjectField";
-import { CompiledScript, CompileScript, scriptingGlobal, ScriptOptions, CompileError, CompileResult } from "../client/util/Scripting";
-import { Copy, ToScriptString, ToString, Parent, SelfProxy } from "./FieldSymbols";
-import { serializable, createSimpleSchema, map, primitive, object, deserialize, PropSchema, custom, SKIP } from "serializr";
-import { Deserializable, autoObject } from "../client/util/SerializationHelper";
-import { Doc, Field } from "../new_fields/Doc";
-import { Plugins, setter } from "./util";
-import { computedFn } from "mobx-utils";
-import { ProxyField } from "./Proxy";
-import { Cast } from "./Types";
-
-function optional(propSchema: PropSchema) {
-    return custom(value => {
-        if (value !== undefined) {
-            return propSchema.serializer(value);
-        }
-        return SKIP;
-    }, (jsonValue: any, context: any, oldValue: any, callback: (err: any, result: any) => void) => {
-        if (jsonValue !== undefined) {
-            return propSchema.deserializer(jsonValue, callback, context, oldValue);
-        }
-        return SKIP;
-    });
-}
-
-const optionsSchema = createSimpleSchema({
-    requiredType: true,
-    addReturn: true,
-    typecheck: true,
-    editable: true,
-    readonly: true,
-    params: optional(map(primitive()))
-});
-
-const scriptSchema = createSimpleSchema({
-    options: object(optionsSchema),
-    originalScript: true
-});
-
-async function deserializeScript(script: ScriptField) {
-    const captures: ProxyField<Doc> = (script as any).captures;
-    if (captures) {
-        const doc = (await captures.value())!;
-        const captured: any = {};
-        const keys = Object.keys(doc);
-        const vals = await Promise.all(keys.map(key => doc[key]) as any);
-        keys.forEach((key, i) => captured[key] = vals[i]);
-        (script.script.options as any).capturedVariables = captured;
-    }
-    const comp = CompileScript(script.script.originalScript, script.script.options);
-    if (!comp.compiled) {
-        throw new Error("Couldn't compile loaded script");
-    }
-    (script as any).script = comp;
-}
-
-@scriptingGlobal
-@Deserializable("script", deserializeScript)
-export class ScriptField extends ObjectField {
-    @serializable(object(scriptSchema))
-    readonly script: CompiledScript;
-    @serializable(object(scriptSchema))
-    readonly setterscript: CompiledScript | undefined;
-
-    @serializable(autoObject())
-    private captures?: ProxyField<Doc>;
-
-    constructor(script: CompiledScript, setterscript?: CompileResult) {
-        super();
-
-        if (script?.options.capturedVariables) {
-            const doc = Doc.assign(new Doc, script.options.capturedVariables);
-            this.captures = new ProxyField(doc);
-        }
-        this.setterscript = setterscript?.compiled ? setterscript : undefined;
-        this.script = script;
-    }
-
-    //     init(callback: (res: Field) => any) {
-    //         const options = this.options!;
-    //         const keys = Object.keys(options.options.capturedIds);
-    //         Server.GetFields(keys).then(fields => {
-    //             let captured: { [name: string]: Field } = {};
-    //             keys.forEach(key => captured[options.options.capturedIds[key]] = fields[key]);
-    //             const opts: ScriptOptions = {
-    //                 addReturn: options.options.addReturn,
-    //                 params: options.options.params,
-    //                 requiredType: options.options.requiredType,
-    //                 capturedVariables: captured
-    //             };
-    //             const script = CompileScript(options.script, opts);
-    //             if (!script.compiled) {
-    //                 throw new Error("Can't compile script");
-    //             }
-    //             this._script = script;
-    //             callback(this);
-    //         });
-    //     }
-
-    [Copy](): ObjectField {
-        return new ScriptField(this.script);
-    }
-    toString() {
-        return `${this.script.originalScript}`;
-    }
-
-    [ToScriptString]() {
-        return "script field";
-    }
-    [ToString]() {
-        return this.script.originalScript;
-    }
-    public static CompileScript(script: string, params: object = {}, addReturn = false, capturedVariables?: { [name: string]: Field }) {
-        const compiled = CompileScript(script, {
-            params: { this: Doc.name, self: Doc.name, _last_: "any", ...params },
-            typecheck: false,
-            editable: true,
-            addReturn: addReturn,
-            capturedVariables
-        });
-        return compiled;
-    }
-    public static MakeFunction(script: string, params: object = {}, capturedVariables?: { [name: string]: Field }) {
-        const compiled = ScriptField.CompileScript(script, params, true, capturedVariables);
-        return compiled.compiled ? new ScriptField(compiled) : undefined;
-    }
-
-    public static MakeScript(script: string, params: object = {}, capturedVariables?: { [name: string]: Field }) {
-        const compiled = ScriptField.CompileScript(script, params, false, capturedVariables);
-        return compiled.compiled ? new ScriptField(compiled) : undefined;
-    }
-}
-
-@scriptingGlobal
-@Deserializable("computed", deserializeScript)
-export class ComputedField extends ScriptField {
-    _lastComputedResult: any;
-    //TODO maybe add an observable cache based on what is passed in for doc, considering there shouldn't really be that many possible values for doc
-    value = computedFn((doc: Doc) => this._valueOutsideReaction(doc));
-    _valueOutsideReaction = (doc: Doc) => this._lastComputedResult = this.script.run({ this: doc, self: Cast(doc.rootDocument, Doc, null) || doc, _last_: this._lastComputedResult }, console.log).result;
-
-
-    constructor(script: CompiledScript, setterscript?: CompiledScript) {
-        super(script,
-            !setterscript && script?.originalScript.includes("self.timecode") ?
-                ScriptField.CompileScript("self['x' + self.timecode] = value", { value: "any" }, true) : setterscript);
-    }
-
-    public static MakeScript(script: string, params: object = {}) {
-        const compiled = ScriptField.CompileScript(script, params, false);
-        return compiled.compiled ? new ComputedField(compiled) : undefined;
-    }
-    public static MakeFunction(script: string, params: object = {}, capturedVariables?: { [name: string]: Field }, setterScript?: string) {
-        const compiled = ScriptField.CompileScript(script, params, true, capturedVariables);
-        const setCompiled = setterScript ? ScriptField.CompileScript(setterScript, params, true, capturedVariables) : undefined;
-        return compiled.compiled ? new ComputedField(compiled, setCompiled?.compiled ? setCompiled : undefined) : undefined;
-    }
-    public static MakeInterpolated(fieldKey: string, interpolatorKey: string) {
-        const getField = ScriptField.CompileScript(`(self['${fieldKey}-indexed'])[self.${interpolatorKey}]`, {}, true, {});
-        const setField = ScriptField.CompileScript(`(self['${fieldKey}-indexed'])[self.${interpolatorKey}] = value`, { value: "any" }, true, {});
-        return getField.compiled ? new ComputedField(getField, setField?.compiled ? setField : undefined) : undefined;
-    }
-}
-
-export namespace ComputedField {
-    let useComputed = true;
-    export function DisableComputedFields() {
-        useComputed = false;
-    }
-
-    export function EnableComputedFields() {
-        useComputed = true;
-    }
-
-    export const undefined = "__undefined";
-
-    export function WithoutComputed<T>(fn: () => T) {
-        DisableComputedFields();
-        try {
-            return fn();
-        } finally {
-            EnableComputedFields();
-        }
-    }
-
-    export function initPlugin() {
-        Plugins.addGetterPlugin((doc, _, value) => {
-            if (useComputed && value instanceof ComputedField) {
-                return { value: value._valueOutsideReaction(doc), shouldReturn: true };
-            }
-        });
-    }
-}
\ No newline at end of file
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
deleted file mode 100644
index 3d784448d..000000000
--- a/src/new_fields/Types.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-import { Field, Opt, FieldResult, Doc } from "./Doc";
-import { List } from "./List";
-import { RefField } from "./RefField";
-import { DateField } from "./DateField";
-import { ScriptField } from "./ScriptField";
-
-export type ToType<T extends InterfaceValue> =
-    T extends "string" ? string :
-    T extends "number" ? number :
-    T extends "boolean" ? boolean :
-    T extends ListSpec<infer U> ? List<U> :
-    // T extends { new(...args: any[]): infer R } ? (R | Promise<R>) : never;
-    T extends DefaultFieldConstructor<infer _U> ? never :
-    T extends { new(...args: any[]): List<Field> } ? never :
-    T extends { new(...args: any[]): infer R } ? R :
-    T extends (doc?: Doc) => infer R ? R : never;
-
-export type ToConstructor<T extends Field> =
-    T extends string ? "string" :
-    T extends number ? "number" :
-    T extends boolean ? "boolean" :
-    T extends List<infer U> ? ListSpec<U> :
-    new (...args: any[]) => T;
-
-export type ToInterface<T extends Interface> = {
-    [P in Exclude<keyof T, "proto">]: T[P] extends DefaultFieldConstructor<infer F> ? Exclude<FieldResult<F>, undefined> : FieldResult<ToType<T[P]>>;
-};
-
-// type ListSpec<T extends Field[]> = { List: ToContructor<Head<T>> | ListSpec<Tail<T>> };
-export type ListSpec<T extends Field> = { List: ToConstructor<T> };
-
-export type DefaultFieldConstructor<T extends Field> = {
-    type: ToConstructor<T>,
-    defaultVal: T
-};
-
-// type ListType<U extends Field[]> = { 0: List<ListType<Tail<U>>>, 1: ToType<Head<U>> }[HasTail<U> extends true ? 0 : 1];
-
-export type Head<T extends any[]> = T extends [any, ...any[]] ? T[0] : never;
-export type Tail<T extends any[]> =
-    ((...t: T) => any) extends ((_: any, ...tail: infer TT) => any) ? TT : [];
-export type HasTail<T extends any[]> = T extends ([] | [any]) ? false : true;
-
-export type InterfaceValue = ToConstructor<Field> | ListSpec<Field> | DefaultFieldConstructor<Field> | ((doc?: Doc) => any);
-//TODO Allow you to optionally specify default values for schemas, which should then make that field not be partial
-export interface Interface {
-    [key: string]: InterfaceValue;
-    // [key: string]: ToConstructor<Field> | ListSpec<Field[]>;
-}
-export type WithoutRefField<T extends Field> = T extends RefField ? never : T;
-
-export type CastCtor = ToConstructor<Field> | ListSpec<Field>;
-
-export function Cast<T extends CastCtor>(field: FieldResult, ctor: T): FieldResult<ToType<T>>;
-export function Cast<T extends CastCtor>(field: FieldResult, ctor: T, defaultVal: WithoutList<WithoutRefField<ToType<T>>> | null): WithoutList<ToType<T>>;
-export function Cast<T extends CastCtor>(field: FieldResult, ctor: T, defaultVal?: ToType<T> | null): FieldResult<ToType<T>> | undefined {
-    if (field instanceof Promise) {
-        return defaultVal === undefined ? field.then(f => Cast(f, ctor) as any) as any : defaultVal === null ? undefined : defaultVal;
-    }
-    if (field !== undefined && !(field instanceof Promise)) {
-        if (typeof ctor === "string") {
-            if (typeof field === ctor) {
-                return field as ToType<T>;
-            }
-        } else if (typeof ctor === "object") {
-            if (field instanceof List) {
-                return field as any;
-            }
-        } else if (field instanceof (ctor as any)) {
-            return field as ToType<T>;
-        }
-    }
-    return defaultVal === null ? undefined : defaultVal;
-}
-
-export function NumCast(field: FieldResult, defaultVal: number | null = 0) {
-    return Cast(field, "number", defaultVal);
-}
-
-export function StrCast(field: FieldResult, defaultVal: string | null = "") {
-    return Cast(field, "string", defaultVal);
-}
-
-export function BoolCast(field: FieldResult, defaultVal: boolean | null = false) {
-    return Cast(field, "boolean", defaultVal);
-}
-export function DateCast(field: FieldResult) {
-    return Cast(field, DateField, null);
-}
-
-export function ScriptCast(field: FieldResult, defaultVal: ScriptField | null = null) {
-    return Cast(field, ScriptField, defaultVal);
-}
-
-type WithoutList<T extends Field> = T extends List<infer R> ? (R extends RefField ? (R | Promise<R>)[] : R[]) : T;
-
-export function FieldValue<T extends Field, U extends WithoutList<T>>(field: FieldResult<T>, defaultValue: U): WithoutList<T>;
-export function FieldValue<T extends Field>(field: FieldResult<T>): Opt<T>;
-export function FieldValue<T extends Field>(field: FieldResult<T>, defaultValue?: T): Opt<T> {
-    return (field instanceof Promise || field === undefined) ? defaultValue : field;
-}
-
-export interface PromiseLike<T> {
-    then(callback: (field: Opt<T>) => void): void;
-}
-export function PromiseValue<T extends Field>(field: FieldResult<T>): PromiseLike<Opt<T>> {
-    return field instanceof Promise ? field : { then(cb: ((field: Opt<T>) => void)) { return cb(field); } };
-}
\ No newline at end of file
diff --git a/src/new_fields/URLField.ts b/src/new_fields/URLField.ts
deleted file mode 100644
index fb71160ca..000000000
--- a/src/new_fields/URLField.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import { Deserializable } from "../client/util/SerializationHelper";
-import { serializable, custom } from "serializr";
-import { ObjectField } from "./ObjectField";
-import { ToScriptString, ToString, Copy } from "./FieldSymbols";
-import { Scripting, scriptingGlobal } from "../client/util/Scripting";
-
-function url() {
-    return custom(
-        function (value: URL) {
-            return value.href;
-        },
-        function (jsonValue: string) {
-            return new URL(jsonValue);
-        }
-    );
-}
-
-export abstract class URLField extends ObjectField {
-    @serializable(url())
-    readonly url: URL;
-
-    constructor(url: string);
-    constructor(url: URL);
-    constructor(url: URL | string) {
-        super();
-        if (typeof url === "string") {
-            url = new URL(url);
-        }
-        this.url = url;
-    }
-
-    [ToScriptString]() {
-        return `new ${this.constructor.name}("${this.url.href}")`;
-    }
-    [ToString]() {
-        return this.url.href;
-    }
-
-    [Copy](): this {
-        return new (this.constructor as any)(this.url);
-    }
-}
-
-export const nullAudio = "https://actions.google.com/sounds/v1/alarms/beep_short.ogg";
-
-@scriptingGlobal @Deserializable("audio") export class AudioField extends URLField { }
-@scriptingGlobal @Deserializable("image") export class ImageField extends URLField { }
-@scriptingGlobal @Deserializable("video") export class VideoField extends URLField { }
-@scriptingGlobal @Deserializable("pdf") export class PdfField extends URLField { }
-@scriptingGlobal @Deserializable("web") export class WebField extends URLField { }
-@scriptingGlobal @Deserializable("youtube") export class YoutubeField extends URLField { }
-@scriptingGlobal @Deserializable("webcam") export class WebCamField extends URLField { }
-
diff --git a/src/new_fields/documentSchemas.ts b/src/new_fields/documentSchemas.ts
deleted file mode 100644
index cacba43b6..000000000
--- a/src/new_fields/documentSchemas.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import { makeInterface, createSchema, listSpec } from "./Schema";
-import { ScriptField } from "./ScriptField";
-import { Doc } from "./Doc";
-import { DateField } from "./DateField";
-
-export const documentSchema = createSchema({
-    // content properties
-    type: "string",             // enumerated type of document -- should be template-specific (ie, start with an '_')
-    title: "string",            // document title (can be on either data document or layout)
-    isTemplateForField: "string",// if specified, it indicates the document is a template that renders the specified field
-    creationDate: DateField,    // when the document was created
-    links: listSpec(Doc),       // computed (readonly) list of links associated with this document
-
-    // "Location" properties in a very general sense
-    currentTimecode: "number",  // current play back time of a temporal document (video / audio)
-    displayTimecode: "number",  // the time that a document should be displayed (e.g., time an annotation should be displayed on a video)
-    inOverlay: "boolean",       // whether the document is rendered in an OverlayView which handles selection/dragging differently
-    x: "number",                // x coordinate when in a freeform view 
-    y: "number",                // y coordinate when in a freeform view 
-    z: "number",                // z "coordinate" - non-zero specifies the overlay layer of a freeformview
-    zIndex: "number",           // zIndex of a document in a freeform view
-    scrollY: "number",          // "command" to scroll a document to a position on load (the value will be reset to 0 after that )
-    scrollTop: "number",        // scroll position of a scrollable document (pdf, text, web)
-
-    // appearance properties on the layout
-    _autoHeight: "boolean",     // whether the height of the document should be computed automatically based on its contents
-    _nativeWidth: "number",     // native width of document which determines how much document contents are scaled when the document's width is set
-    _nativeHeight: "number",    // "
-    _width: "number",           // width of document in its container's coordinate system
-    _height: "number",          // "
-    _xPadding: "number",        // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
-    _yPadding: "number",        // pixels of padding on top/bottom of collectionfreeformview contents when fitToBox is set
-    _xMargin: "number",         // margin added on left/right of most documents to add separation from their container
-    _yMargin: "number",         // margin added on top/bottom of most documents to add separation from their container
-    _overflow: "string",        // sets overflow behvavior for CollectionFreeForm views
-    _showCaption: "string",     // whether editable caption text is overlayed at the bottom of the document 
-    _showTitle: "string",       // the fieldkey whose contents should be displayed at the top of the document
-    _showTitleHover: "string",  // the showTitle should be shown only on hover
-    _showAudio: "boolean",      // whether to show the audio record icon on documents
-    _freeformLayoutEngine: "string",// the string ID for the layout engine to use to layout freeform view documents
-    _LODdisable: "boolean",     // whether to disbale LOD switching for CollectionFreeFormViews
-    _pivotField: "string",      // specifies which field key should be used as the timeline/pivot axis
-    _replacedChrome: "string",  // what the default chrome is replaced with. Currently only supports the value of 'replaced' for PresBox's.
-    _chromeStatus: "string",    // determines the state of the collection chrome. values allowed are 'replaced', 'enabled', 'disabled', 'collapsed'
-    _fontSize: "number",
-    _fontFamily: "string",
-    _sidebarWidthPercent: "string", // percent of text window width taken up by sidebar
-
-    // appearance properties on the data document
-    backgroundColor: "string",  // background color of document
-    borderRounding: "string",   // border radius rounding of document
-    boxShadow: "string",        // the amount of shadow around the perimeter of a document
-    color: "string",            // foreground color of document
-    fitToBox: "boolean",        // whether freeform view contents should be zoomed/panned to fill the area of the document view
-    fontSize: "string",
-    layout: "string",           // this is the native layout string for the document.  templates can be added using other fields and setting layoutKey below
-    layoutKey: "string",        // holds the field key for the field that actually holds the current lyoat
-    letterSpacing: "string",
-    opacity: "number",          // opacity of document
-    strokeWidth: "number",
-    textTransform: "string",
-    treeViewOpen: "boolean",    //  flag denoting whether the documents sub-tree (contents) is visible or hidden
-    treeViewExpandedView: "string", // name of field whose contents are being displayed as the document's subtree
-    treeViewPreventOpen: "boolean", // ignores the treeViewOpen flag (for allowing a view to not be slaved to other views of the document)
-
-    // interaction and linking properties
-    ignoreClick: "boolean",     // whether documents ignores input clicks (but does not ignore manipulation and other events) 
-    onClick: ScriptField,       // script to run when document is clicked (can be overriden by an onClick prop)
-    onPointerDown: ScriptField, // script to run when document is clicked (can be overriden by an onClick prop)
-    onPointerUp: ScriptField,   // script to run when document is clicked (can be overriden by an onClick prop)
-    onDragStart: ScriptField,   // script to run when document is dragged (without being selected).  the script should return the Doc to be dropped.
-    followLinkLocation: "string",// flag for where to place content when following a click interaction (e.g., onRight, inPlace, inTab, ) 
-    isInPlaceContainer: "boolean",// whether the marked object will display addDocTab() calls that target "inPlace" destinations
-    isLinkButton: "boolean",    // whether document functions as a link follow button to follow the first link on the document when clicked   
-    isBackground: "boolean",    // whether document is a background element and ignores input events (can only select with marquee)
-    lockedPosition: "boolean",  // whether the document can be moved (dragged)
-    lockedTransform: "boolean", // whether the document can be panned/zoomed
-
-    // drag drop properties
-    dragFactory: Doc,           // the document that serves as the "template" for the onDragStart script.  ie, to drag out copies of the dragFactory document.
-    dropAction: "string",       // override specifying what should happen when this document is dropped (can be "alias", "copy", "move")
-    targetDropAction: "string", // allows the target of a drop event to specify the dropAction ("alias", "copy", "move") NOTE: if the document is dropped within the same collection, the dropAction is coerced to 'move'
-    childDropAction: "string",  // specify the override for what should happen when the child of a collection is dragged from it and dropped (can be "alias" or "copy")
-    removeDropProperties: listSpec("string"), // properties that should be removed from the alias/copy/etc of this document when it is dropped
-});
-
-
-export const collectionSchema = createSchema({
-    childLayoutTemplateName: "string", // the name of a template to use to override the layoutKey when rendering a document -- ONLY used in DocHolderBox 
-    childLayoutTemplate: Doc, // layout template to use to render children of a collecion
-    childLayoutString: "string", //layout string to use to render children of a collection
-    childClickedOpenTemplateView: Doc, // layout template to apply to a child when its clicked on in a collection and opened (requires onChildClick or other script to read this value and apply template)
-    dontRegisterChildViews: "boolean", // whether views made of this document are registered so that they can be found when drawing links scrollToLinkID: "string",   // id of link being traversed. allows this doc to scroll/highlight/etc its link anchor. scrollToLinkID should be set to undefined by this doc after it sets up its scroll,etc.
-    onChildClick: ScriptField, // script to run for each child when its clicked
-    onChildDoubleClick: ScriptField, // script to run for each child when its clicked
-    onCheckedClick: ScriptField, // script to run when a checkbox is clicked next to a child in a tree view
-});
-
-export type Document = makeInterface<[typeof documentSchema]>;
-export const Document = makeInterface(documentSchema);
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
deleted file mode 100644
index a287b0210..000000000
--- a/src/new_fields/util.ts
+++ /dev/null
@@ -1,199 +0,0 @@
-import { UndoManager } from "../client/util/UndoManager";
-import { Doc, Field, FieldResult, UpdatingFromServer, LayoutSym } from "./Doc";
-import { SerializationHelper } from "../client/util/SerializationHelper";
-import { ProxyField, PrefetchProxy } from "./Proxy";
-import { RefField } from "./RefField";
-import { ObjectField } from "./ObjectField";
-import { action, trace } from "mobx";
-import { Parent, OnUpdate, Update, Id, SelfProxy, Self } from "./FieldSymbols";
-import { DocServer } from "../client/DocServer";
-import { ComputedField } from "./ScriptField";
-import { ScriptCast } from "./Types";
-
-function _readOnlySetter(): never {
-    throw new Error("Documents can't be modified in read-only mode");
-}
-
-const tracing = false;
-export function TraceMobx() {
-    tracing && trace();
-}
-
-export interface GetterResult {
-    value: FieldResult;
-    shouldReturn?: boolean;
-}
-export type GetterPlugin = (receiver: any, prop: string | number, currentValue: any) => GetterResult | undefined;
-const getterPlugins: GetterPlugin[] = [];
-
-export namespace Plugins {
-    export function addGetterPlugin(plugin: GetterPlugin) {
-        getterPlugins.push(plugin);
-    }
-}
-
-const _setterImpl = action(function (target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
-    //console.log("-set " + target[SelfProxy].title + "(" + target[SelfProxy][prop] + ")." + prop.toString() + " = " + value);
-    if (SerializationHelper.IsSerializing()) {
-        target[prop] = value;
-        return true;
-    }
-
-    if (typeof prop === "symbol") {
-        target[prop] = value;
-        return true;
-    }
-    if (value !== undefined) {
-        value = value[SelfProxy] || value;
-    }
-    const curValue = target.__fields[prop];
-    if (curValue === value || (curValue instanceof ProxyField && value instanceof RefField && curValue.fieldId === value[Id])) {
-        // TODO This kind of checks correctly in the case that curValue is a ProxyField and value is a RefField, but technically
-        // curValue should get filled in with value if it isn't already filled in, in case we fetched the referenced field some other way
-        return true;
-    }
-    if (value instanceof RefField) {
-        value = new ProxyField(value);
-    }
-    if (value instanceof ObjectField) {
-        if (value[Parent] && value[Parent] !== receiver && !(value instanceof PrefetchProxy)) {
-            throw new Error("Can't put the same object in multiple documents at the same time");
-        }
-        value[Parent] = receiver;
-        value[OnUpdate] = updateFunction(target, prop, value, receiver);
-    }
-    if (curValue instanceof ObjectField) {
-        delete curValue[Parent];
-        delete curValue[OnUpdate];
-    }
-    const writeMode = DocServer.getFieldWriteMode(prop as string);
-    const fromServer = target[UpdatingFromServer];
-    const sameAuthor = fromServer || (receiver.author === Doc.CurrentUserEmail);
-    const writeToDoc = sameAuthor || (writeMode !== DocServer.WriteMode.LiveReadonly);
-    const writeToServer = sameAuthor || (writeMode === DocServer.WriteMode.Default);
-    if (writeToDoc) {
-        if (value === undefined) {
-            delete target.__fields[prop];
-        } else {
-            target.__fields[prop] = value;
-        }
-        if (typeof value === "object" && !(value instanceof ObjectField)) debugger;
-        if (writeToServer) {
-            if (value === undefined) target[Update]({ '$unset': { ["fields." + prop]: "" } });
-            else target[Update]({ '$set': { ["fields." + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) : (value === undefined ? null : value) } });
-        } else {
-            DocServer.registerDocWithCachedUpdate(receiver, prop as string, curValue);
-        }
-        UndoManager.AddEvent({
-            redo: () => receiver[prop] = value,
-            undo: () => receiver[prop] = curValue
-        });
-    }
-    return true;
-});
-
-let _setter: (target: any, prop: string | symbol | number, value: any, receiver: any) => boolean = _setterImpl;
-
-export function makeReadOnly() {
-    _setter = _readOnlySetter;
-}
-
-export function makeEditable() {
-    _setter = _setterImpl;
-}
-
-const layoutProps = ["panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "fitWidth", "fitToBox",
-    "LODdisable", "chromeStatus", "viewType", "gridGap", "xMargin", "yMargin", "autoHeight"];
-export function setter(target: any, in_prop: string | symbol | number, value: any, receiver: any): boolean {
-    let prop = in_prop;
-    if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && (prop.startsWith("_") || layoutProps.includes(prop))) {
-        if (!prop.startsWith("_")) {
-            console.log(prop + " is deprecated - switch to _" + prop);
-            prop = "_" + prop;
-        }
-        if (target.__LAYOUT__) {
-            target.__LAYOUT__[prop] = value;
-            return true;
-        }
-    }
-    if (target.__fields[prop] instanceof ComputedField && target.__fields[prop].setterscript) {
-        return ScriptCast(target.__fields[prop])?.setterscript?.run({ self: target[SelfProxy], this: target[SelfProxy], value }).success ? true : false;
-    }
-    return _setter(target, prop, value, receiver);
-}
-
-export function getter(target: any, in_prop: string | symbol | number, receiver: any): any {
-    let prop = in_prop;
-    if (prop === LayoutSym) {
-        return target.__LAYOUT__;
-    }
-    if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && (prop.startsWith("_") || layoutProps.includes(prop))) {
-        if (!prop.startsWith("_")) {
-            console.log(prop + " is deprecated - switch to _" + prop);
-            prop = "_" + prop;
-        }
-        if (target.__LAYOUT__) return target.__LAYOUT__[prop];
-    }
-    if (prop === "then") {//If we're being awaited
-        return undefined;
-    }
-    if (typeof prop === "symbol") {
-        return target.__fields[prop] || target[prop];
-    }
-    if (SerializationHelper.IsSerializing()) {
-        return target[prop];
-    }
-    return getFieldImpl(target, prop, receiver);
-}
-
-function getFieldImpl(target: any, prop: string | number, receiver: any, ignoreProto: boolean = false): any {
-    receiver = receiver || target[SelfProxy];
-    let field = target.__fields[prop];
-    for (const plugin of getterPlugins) {
-        const res = plugin(receiver, prop, field);
-        if (res === undefined) continue;
-        if (res.shouldReturn) {
-            return res.value;
-        } else {
-            field = res.value;
-        }
-    }
-    if (field === undefined && !ignoreProto && prop !== "proto") {
-        const proto = getFieldImpl(target, "proto", receiver, true);//TODO tfs: instead of receiver we could use target[SelfProxy]... I don't which semantics we want or if it really matters
-        if (proto instanceof Doc) {
-            return getFieldImpl(proto[Self], prop, receiver, ignoreProto);
-        }
-        return undefined;
-    }
-    return field;
-
-}
-export function getField(target: any, prop: string | number, ignoreProto: boolean = false): any {
-    return getFieldImpl(target, prop, undefined, ignoreProto);
-}
-
-export function deleteProperty(target: any, prop: string | number | symbol) {
-    if (typeof prop === "symbol") {
-        delete target[prop];
-        return true;
-    }
-    target[SelfProxy][prop] = undefined;
-    return true;
-}
-
-export function updateFunction(target: any, prop: any, value: any, receiver: any) {
-    let current = ObjectField.MakeCopy(value);
-    return (diff?: any) => {
-        if (true || !diff) {
-            diff = { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } };
-            const oldValue = current;
-            const newValue = ObjectField.MakeCopy(value);
-            current = newValue;
-            UndoManager.AddEvent({
-                redo() { receiver[prop] = newValue; },
-                undo() { receiver[prop] = oldValue; }
-            });
-        }
-        target[Update](diff);
-    };
-}
\ No newline at end of file
diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts
index b8a82ab4d..3b6170f68 100644
--- a/src/pen-gestures/GestureUtils.ts
+++ b/src/pen-gestures/GestureUtils.ts
@@ -1,9 +1,9 @@
 import { NDollarRecognizer } from "./ndollar";
 import { Type } from "typescript";
-import { InkField, PointData } from "../new_fields/InkField";
+import { InkField, PointData } from "../fields/InkField";
 import { Docs } from "../client/documents/Documents";
-import { Doc, WidthSym, HeightSym } from "../new_fields/Doc";
-import { NumCast } from "../new_fields/Types";
+import { Doc, WidthSym, HeightSym } from "../fields/Doc";
+import { NumCast } from "../fields/Types";
 import { CollectionFreeFormView } from "../client/views/collections/collectionFreeForm/CollectionFreeFormView";
 import { Rect } from "react-measure";
 import { Scripting } from "../client/util/Scripting";
diff --git a/src/server/ApiManagers/GooglePhotosManager.ts b/src/server/ApiManagers/GooglePhotosManager.ts
index 11841a603..be17b698e 100644
--- a/src/server/ApiManagers/GooglePhotosManager.ts
+++ b/src/server/ApiManagers/GooglePhotosManager.ts
@@ -3,7 +3,7 @@ import { Method, _error, _success, _invalid } from "../RouteManager";
 import * as path from "path";
 import { GoogleApiServerUtils } from "../apis/google/GoogleApiServerUtils";
 import { BatchedArray, TimeUnit } from "array-batcher";
-import { Opt } from "../../new_fields/Doc";
+import { Opt } from "../../fields/Doc";
 import { DashUploadUtils, InjectSize, SizeSuffix } from "../DashUploadUtils";
 import { Database } from "../database";
 import { red } from "colors";
diff --git a/src/server/ApiManagers/UserManager.ts b/src/server/ApiManagers/UserManager.ts
index 68b3107ae..0d1d8f218 100644
--- a/src/server/ApiManagers/UserManager.ts
+++ b/src/server/ApiManagers/UserManager.ts
@@ -3,7 +3,7 @@ import { Method } from "../RouteManager";
 import { Database } from "../database";
 import { msToTime } from "../ActionUtilities";
 import * as bcrypt from "bcrypt-nodejs";
-import { Opt } from "../../new_fields/Doc";
+import { Opt } from "../../fields/Doc";
 
 export const timeMap: { [id: string]: number } = {};
 interface ActivityUnit {
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index 8567631cd..b74904ada 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -4,7 +4,7 @@ import * as path from 'path';
 import * as sharp from 'sharp';
 import request = require('request-promise');
 import { ExifImage } from 'exif';
-import { Opt } from '../new_fields/Doc';
+import { Opt } from '../fields/Doc';
 import { AcceptibleMedia, Upload } from './SharedMediaTypes';
 import { filesDirectory, publicDirectory } from '.';
 import { File } from 'formidable';
diff --git a/src/server/Message.ts b/src/server/Message.ts
index 01aae5de7..80f372733 100644
--- a/src/server/Message.ts
+++ b/src/server/Message.ts
@@ -1,6 +1,6 @@
 import { Utils } from "../Utils";
 import { Point } from "../pen-gestures/ndollar";
-import { Doc } from "../new_fields/Doc";
+import { Doc } from "../fields/Doc";
 import { Image } from "canvas";
 import { AnalysisResult, ImportResults } from "../scraping/buxton/final/BuxtonImporter";
 
diff --git a/src/server/Recommender.ts b/src/server/Recommender.ts
index aacdb4053..423ce9b46 100644
--- a/src/server/Recommender.ts
+++ b/src/server/Recommender.ts
@@ -1,6 +1,6 @@
-// //import { Doc } from "../new_fields/Doc";
-// //import { StrCast } from "../new_fields/Types";
-// //import { List } from "../new_fields/List";
+// //import { Doc } from "../fields/Doc";
+// //import { StrCast } from "../fields/Types";
+// //import { List } from "../fields/List";
 // //import { CognitiveServices } from "../client/cognitive_services/CognitiveServices";
 
 // // var w2v = require('word2vec');
diff --git a/src/server/apis/google/GoogleApiServerUtils.ts b/src/server/apis/google/GoogleApiServerUtils.ts
index 2e4811c86..20f96f432 100644
--- a/src/server/apis/google/GoogleApiServerUtils.ts
+++ b/src/server/apis/google/GoogleApiServerUtils.ts
@@ -1,6 +1,6 @@
 import { google } from "googleapis";
 import { OAuth2Client, Credentials, OAuth2ClientOptions } from "google-auth-library";
-import { Opt } from "../../../new_fields/Doc";
+import { Opt } from "../../../fields/Doc";
 import { GaxiosResponse } from "gaxios";
 import request = require('request-promise');
 import * as qs from "query-string";
diff --git a/src/server/database.ts b/src/server/database.ts
index ed9a246e3..a5f23c4b1 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -1,6 +1,6 @@
 import * as mongodb from 'mongodb';
 import { Transferable } from './Message';
-import { Opt } from '../new_fields/Doc';
+import { Opt } from '../fields/Doc';
 import { Utils, emptyFunction } from '../Utils';
 import { Credentials } from 'google-auth-library';
 import { GoogleApiServerUtils } from './apis/google/GoogleApiServerUtils';
diff --git a/test/test.ts b/test/test.ts
index 245733e9b..5fc156b46 100644
--- a/test/test.ts
+++ b/test/test.ts
@@ -8,10 +8,10 @@ const dom = new JSDOM("", {
 
 
 import { autorun, reaction } from "mobx";
-import { Doc } from '../src/new_fields/Doc';
-import { Cast } from '../src/new_fields/Types';
-import { createSchema, makeInterface, defaultSpec } from '../src/new_fields/Schema';
-import { ImageField } from '../src/new_fields/URLField';
+import { Doc } from '../src/fields/Doc';
+import { Cast } from '../src/fields/Types';
+import { createSchema, makeInterface, defaultSpec } from '../src/fields/Schema';
+import { ImageField } from '../src/fields/URLField';
 describe("Document", () => {
     it('should hold fields', () => {
         const key = "Test";
-- 
cgit v1.2.3-70-g09d2


From a0dc46dc565418fef9a257508a92c788c4ec50af Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 16 May 2020 00:01:06 -0400
Subject: fixed some issues with frame animation.  added comic rendering mode. 
 added server certficate keys to get SSL to work?

---
 src/client/views/MainView.tsx                      |  6 ++--
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 16 +++++----
 .../collections/collectionFreeForm/MarqueeView.tsx |  2 +-
 .../views/nodes/CollectionFreeFormDocumentView.tsx | 14 ++++++--
 src/client/views/nodes/DocumentView.tsx            |  2 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |  3 +-
 src/server/server_Initialization.ts                | 39 +++++++++++-----------
 7 files changed, 48 insertions(+), 34 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index f58313f06..3e4833052 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -256,8 +256,9 @@ export class MainView extends React.Component {
         const mainDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [Doc.UserDoc().myCatalog as Doc] }], { title: `Workspace ${workspaceCount}` }, id, "row");
 
         const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`);
-        mainDoc.contextMenuScripts = new List<ScriptField>([toggleTheme!]);
-        mainDoc.contextMenuLabels = new List<string>(["Toggle Theme Colors"]);
+        const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
+        mainDoc.contextMenuScripts = new List<ScriptField>([toggleTheme!, toggleComic!]);
+        mainDoc.contextMenuLabels = new List<string>(["Toggle Theme Colors", "Toggle Comic Mode"]);
 
         Doc.AddDocToList(workspaces, "data", mainDoc);
         // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
@@ -629,3 +630,4 @@ export class MainView extends React.Component {
     }
 }
 Scripting.addGlobal(function freezeSidebar() { MainView.expandFlyout(); });
+Scripting.addGlobal(function toggleComicMode() { Doc.UserDoc().fontFamily = "Comic Sans MS"; Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic" });
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 4be671a76..d27f3bb0d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -155,6 +155,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     @undoBatch
     @action
     prevKeyframe = (): void => {
+        if (this.props.Document.timecode === undefined) {
+            this.props.Document.timecode = 0;
+            CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0, this.props.Document);
+        }
         CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice());
         this.props.Document.timecode = Math.max(0, NumCast(this.props.Document.timecode) - 1);
     }
@@ -1095,7 +1099,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                         this.backgroundActive ?
                             true :
                             (this.props.viewDefDivClick || (engine === "pass" && !this.props.isSelected(true))) ? false : undefined}
-                    jitterRotation={NumCast(this.props.Document._jitterRotation)}
+                    jitterRotation={NumCast(this.props.Document._jitterRotation) || ((Doc.UserDoc().renderStyle === "comic" ? 10 : 0))}
                     //fitToBox={this.props.fitToBox || BoolCast(this.props.freezeChildDimensions)} // bcz: check this
                     fitToBox={BoolCast(this.props.freezeChildDimensions)} // bcz: check this
                     FreezeDimensions={BoolCast(this.props.freezeChildDimensions)}
@@ -1352,14 +1356,14 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             <CollectionFreeFormOverlayView elements={this.elementFunc} />
             {this.isAnnotationOverlay ? (null) :
                 <>
-                    <div key="fwd" className="backKeyframe" onClick={this.nextKeyframe}>
-                        <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
+                    <div key="back" className="backKeyframe" onClick={this.prevKeyframe}>
+                        <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
                     </div>
-                    <div key="fwd" className="numKeyframe" >
+                    <div key="num" className="numKeyframe" >
                         {NumCast(this.props.Document.timecode)}
                     </div>
-                    <div key="back" className="fwdKeyframe" onClick={this.prevKeyframe}>
-                        <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
+                    <div key="fwd" className="fwdKeyframe" onClick={this.nextKeyframe}>
+                        <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
                     </div>
                 </>}
             <div className={"pullpane-indicator"}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 492ba6ed6..911a2bc3b 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -107,7 +107,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
             FormattedTextBox.SelectOnLoadChar = FormattedTextBox.DefaultLayout ? e.key : "";
             const tbox = Docs.Create.TextDocument("", {
                 _width: 200, _height: 100, x: x, y: y, _autoHeight: true, _fontSize: NumCast(Doc.UserDoc().fontSize),
-                _backgroundColor: StrCast(Doc.UserDoc().backgroundColor),
+                _fontFamily: StrCast(Doc.UserDoc().fontFamily), _backgroundColor: StrCast(Doc.UserDoc().backgroundColor),
                 title: "-typed text-"
             });
             const template = FormattedTextBox.DefaultLayout;
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 5d109a5f2..c9bb543f1 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -87,9 +87,9 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             const xindexed = Cast(doc['x-indexed'], listSpec("number"), null);
             const yindexed = Cast(doc['y-indexed'], listSpec("number"), null);
             const opacityindexed = Cast(doc['opacity-indexed'], listSpec("number"), null);
-            xindexed.length <= timecode + 1 && xindexed.push(undefined as any as number);
-            yindexed.length <= timecode + 1 && yindexed.push(undefined as any as number);
-            opacityindexed.length <= timecode + 1 && opacityindexed.push(undefined as any as number);
+            xindexed?.length <= timecode + 1 && xindexed.push(undefined as any as number);
+            yindexed?.length <= timecode + 1 && yindexed.push(undefined as any as number);
+            opacityindexed?.length <= timecode + 1 && opacityindexed.push(undefined as any as number);
             doc.transition = "all 1s";
         });
         setTimeout(() => docs.forEach(doc => doc.transition = undefined), 1010);
@@ -129,6 +129,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     NativeHeight = () => this.nativeHeight;
     render() {
         TraceMobx();
+        const backgroundColor = StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document);
         return <div className="collectionFreeFormDocumentView-container"
             style={{
                 boxShadow:
@@ -148,6 +149,13 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                 display: this.ZInd === -99 ? "none" : undefined,
                 pointerEvents: this.props.Document.isBackground || this.Opacity === 0 ? "none" : this.props.pointerEvents ? "all" : undefined
             }} >
+            {Doc.UserDoc().renderStyle !== "comic" ? (null) :
+                <div style={{ width: "100%", height: "100%", position: "absolute" }}>
+                    <svg style={{ transform: `scale(1,${this.props.PanelHeight() / this.props.PanelWidth()})`, transformOrigin: "top left", overflow: "visible" }} viewBox="0 0 12 14">
+                        <path d="M 7 0 C 9 -1 13 1 12 4 C 11 10 13 12 10 12 C 6 12 7 13 2 12 Q -1 11 0 8 C 1 4 0 4 0 2 C 0 0 1 0 1 0 C 3 0 3 1 7 0"
+                            style={{ stroke: "black", fill: backgroundColor, strokeWidth: 0.2 }} />
+                    </svg>
+                </div>}
 
             {!this.props.fitToBox ?
                 <DocumentView {...this.props}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 340fa06a8..2048be6fb 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1118,7 +1118,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     render() {
         if (!(this.props.Document instanceof Doc)) return (null);
-        const backgroundColor = StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document);
+        const backgroundColor = Doc.UserDoc().renderStyle === "comic" ? undefined : StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document);
         const finalColor = this.layoutDoc.type === DocumentType.FONTICON || this.layoutDoc._viewType === CollectionViewType.Linear ? undefined : backgroundColor;
         const fullDegree = Doc.isBrushedHighlightedDegree(this.props.Document);
         const borderRounding = this.layoutDoc.borderRounding;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 5e33e7e70..a00eb366b 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -206,6 +206,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 if ((!curTemp && !curProto) || curText || curLayout?.Data.includes("dash")) { // if no template, or there's text that didn't come from the layout template, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended)
                     if (json !== curLayout?.Data) {
                         !curText && tx.storedMarks?.map(m => m.type.name === "pFontSize" && (Doc.UserDoc().fontSize = this.layoutDoc._fontSize = m.attrs.fontSize));
+                        !curText && tx.storedMarks?.map(m => m.type.name === "pFontFamily" && (Doc.UserDoc().fontFamily = this.layoutDoc._fontFamily = m.attrs.fontFamily));
                         this.dataDoc[this.props.fieldKey] = new RichTextField(json, curText);
                         this.dataDoc[this.props.fieldKey + "-noTemplate"] = (curTemp?.Text || "") !== curText; // mark the data field as being split from the template if it has been edited
                     }
@@ -1230,7 +1231,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                     style={{
                         width: "100%",
                         height: this.props.height ? this.props.height : this.layoutDoc._autoHeight && this.props.renderDepth ? "max-content" : `calc(100% - ${this.props.ChromeHeight?.() || 0}px`,
-                        background: this.props.background ? this.props.background : StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], this.props.hideOnLeave ? "rgba(0,0,0 ,0.4)" : ""),
+                        background: Doc.UserDoc().renderStyle === "comic" ? "transparent" : this.props.background ? this.props.background : StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], this.props.hideOnLeave ? "rgba(0,0,0 ,0.4)" : ""),
                         opacity: this.props.hideOnLeave ? (this._entered ? 1 : 0.1) : 1,
                         color: this.props.color ? this.props.color : StrCast(this.layoutDoc[this.props.fieldKey + "-color"], this.props.hideOnLeave ? "white" : "inherit"),
                         pointerEvents: interactive ? "none" : undefined,
diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts
index 14b0dedc3..6866b01e3 100644
--- a/src/server/server_Initialization.ts
+++ b/src/server/server_Initialization.ts
@@ -22,6 +22,7 @@ import { publicDirectory } from '.';
 import { logPort, } from './ActionUtilities';
 import { blue, yellow } from 'colors';
 import * as cors from "cors";
+var https = require('https');
 
 /* RouteSetter is a wrapper around the server that prevents the server
    from being exposed. */
@@ -49,27 +50,25 @@ export default async function InitializeServer(routeSetter: RouteSetter) {
     registerRelativePath(app);
 
     const serverPort = isRelease ? Number(process.env.serverPort) : 1050;
-    const server = app.listen(serverPort, () => {
-        logPort("server", serverPort);
-        console.log();
-    });
 
-    // var express = require('express')
-    // var fs = require('fs')
-    // var https = require('https')
-    // var app = express()
-
-    // app.get('/', function (req, res) {
-    //   res.send('hello world')
-    // })
-
-    // https.createServer({
-    //   key: fs.readFileSync('server.key'),
-    //   cert: fs.readFileSync('server.cert')
-    // }, app)
-    // .listen(3000, function () {
-    //   console.log('Example app listening on port 3000! Go to https://localhost:3000/')
-    // })
+    let server: any;
+    if (isRelease) {
+        server = https.createServer({
+            key: fs.readFileSync(`./${process.env.serverName}.key`),
+            cert: fs.readFileSync(`./${process.env.serverName}.cert`)
+        }, app);
+        server.listen(serverPort, function () {
+            logPort("server", serverPort);
+            console.log();
+            // console.log('Example app listening on port 3000! Go to https://localhost:3000/')
+        });
+    } else {
+        server = app.listen(serverPort, () => {
+            logPort("server", serverPort);
+            console.log();
+        });
+    }
+
     disconnect = async () => new Promise<Error>(resolve => server.close(resolve));
 
     return isRelease;
-- 
cgit v1.2.3-70-g09d2


From ceb616873f76ee19549306a735a09697a56291a2 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 16 May 2020 20:03:34 -0400
Subject: fixed copying of computed fields (bug when aliasing animated
 collections).  fixed opacity for presentation view. renamed timecode to match
 with video timecodes.

---
 .../views/collections/CollectionStackingView.tsx   |  1 +
 src/client/views/collections/CollectionSubView.tsx |  1 +
 src/client/views/collections/CollectionView.tsx    |  1 +
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 45 +++++++++++-----------
 .../views/nodes/CollectionFreeFormDocumentView.tsx | 15 ++++----
 src/client/views/nodes/DocumentView.tsx            |  5 ++-
 src/client/views/nodes/PresBox.tsx                 |  3 +-
 .../views/presentationview/PresElementBox.tsx      |  1 +
 src/fields/Doc.ts                                  |  2 +-
 src/fields/ScriptField.ts                          |  8 +++-
 10 files changed, 47 insertions(+), 35 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index cc6077d98..421bf90c1 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -213,6 +213,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
             onClick={this.onChildClickHandler}
             onDoubleClick={this.onChildDoubleClickHandler}
             ScreenToLocalTransform={dxf}
+            opacity={this.props.childOpacity}
             focus={this.focusDocument}
             ContainingCollectionDoc={this.props.CollectionView?.props.Document}
             ContainingCollectionView={this.props.CollectionView}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index c9eb08b45..0827f8782 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -44,6 +44,7 @@ export interface SubCollectionViewProps extends CollectionViewProps {
     CollectionView: Opt<CollectionView>;
     children?: never | (() => JSX.Element[]) | React.ReactNode;
     ChildLayoutTemplate?: () => Doc;
+    childOpacity?:() => number;
     ChildLayoutString?: string;
     childClickScript?: ScriptField;
     childDoubleClickScript?: ScriptField;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 3b2e5e4fc..acb66acdb 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -72,6 +72,7 @@ export interface CollectionViewCustomProps {
     filterAddDocument: (doc: Doc | Doc[]) => boolean;  // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example)
     childLayoutTemplate?: () => Opt<Doc>;  // specify a layout Doc template to use for children of the collection
     childLayoutString?: string;  // specify a layout string to use for children of the collection
+    childOpacity?:() => number;
 }
 
 export interface CollectionRenderProps {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index d27f3bb0d..e66e95d81 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -54,7 +54,8 @@ export const panZoomSchema = createSchema({
     _panX: "number",
     _panY: "number",
     scale: "number",
-    timecode: "number",
+    currentTimecode: "number",
+    displayTimecode: "number",
     arrangeScript: ScriptField,
     arrangeInit: ScriptField,
     useClusters: "boolean",
@@ -126,8 +127,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         this.addDocument(newBox);
     }
     addDocument = (newBox: Doc | Doc[]) => {
-        if (this.Document.timecode !== undefined) {
-            CollectionFreeFormDocumentView.setupKeyframes((newBox instanceof Doc) ? [newBox] : newBox, this.Document.timecode, this.props.Document);
+        if (this.Document.currentTimecode !== undefined) {
+            CollectionFreeFormDocumentView.setupKeyframes((newBox instanceof Doc) ? [newBox] : newBox, this.Document.currentTimecode, this.props.Document);
         }
 
         if (newBox instanceof Doc) {
@@ -144,23 +145,24 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     @undoBatch
     @action
     nextKeyframe = (): void => {
-        if (this.props.Document.timecode === undefined) {
-            this.props.Document.timecode = 0;
+        const currentTimecode = this.Document.currentTimecode;
+        if (currentTimecode === undefined) {
+            this.Document.currentTimecode = 0;
             CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0, this.props.Document);
         }
-        const timecode = NumCast(this.props.Document.timecode);
-        CollectionFreeFormDocumentView.updateKeyframe(this.childDocs, timecode);
-        this.props.Document.timecode = Math.max(0, timecode + 1);
+        CollectionFreeFormDocumentView.updateKeyframe(this.childDocs, currentTimecode || 0);
+        this.Document.currentTimecode = Math.max(0, (currentTimecode || 0) + 1);
     }
     @undoBatch
     @action
     prevKeyframe = (): void => {
-        if (this.props.Document.timecode === undefined) {
-            this.props.Document.timecode = 0;
+        const currentTimecode = this.Document.currentTimecode;
+        if (currentTimecode === undefined) {
+            this.Document.currentTimecode = 0;
             CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0, this.props.Document);
         }
         CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice());
-        this.props.Document.timecode = Math.max(0, NumCast(this.props.Document.timecode) - 1);
+        this.Document.currentTimecode = Math.max(0, (currentTimecode || 0) - 1);
     }
 
     private selectDocuments = (docs: Doc[]) => {
@@ -203,8 +205,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                         for (let i = 0; i < droppedDocs.length; i++) {
                             const d = droppedDocs[i];
                             const layoutDoc = Doc.Layout(d);
-                            if (this.Document.timecode !== undefined) {
-                                CollectionFreeFormDocumentView.setValues(this.Document.timecode, d, x + NumCast(d.x) - dropX, y + NumCast(d.y) - dropY, Cast(d.opacity, "number", null));
+                            if (this.Document.currentTimecode !== undefined) {
+                                CollectionFreeFormDocumentView.setValues(this.Document.currentTimecode, d, x + NumCast(d.x) - dropX, y + NumCast(d.y) - dropY, Cast(d.opacity, "number", null));
                             } else {
                                 d.x = x + NumCast(d.x) - dropX;
                                 d.y = y + NumCast(d.y) - dropY;
@@ -975,11 +977,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             return { x: 0, y: 0, transition: "transform 1s", ...result, pair: params.pair, replica: "" };
         }
         const layoutDoc = Doc.Layout(params.pair.layout);
-        const { x, y, opacity } = this.Document.timecode === undefined ? params.pair.layout :
-            CollectionFreeFormDocumentView.getValues(params.pair.layout, this.Document.timecode);
-        if (this.Document.timecode !== undefined) {
-            const time = this.Document.timecode || 0;
-        }
+        const { x, y, opacity } = this.Document.currentTimecode === undefined ? params.pair.layout :
+            CollectionFreeFormDocumentView.getValues(params.pair.layout, this.Document.currentTimecode || 0);
         const { z, color, zIndex } = params.pair.layout;
         return {
             x: NumCast(x), y: NumCast(y), z: Cast(z, "number"), color: StrCast(color), zIndex: Cast(zIndex, "number"),
@@ -1043,8 +1042,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     doFreeformLayout(poolData: Map<string, PoolData>) {
         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);
-        const state = initResult && initResult.success ? initResult.result.scriptState : undefined;
-        const elements = initResult && initResult.success ? this.viewDefsToJSX(initResult.result.views) : [];
+        const state = initResult?.success ? initResult.result.scriptState : undefined;
+        const elements = initResult?.success ? this.viewDefsToJSX(initResult.result.views) : [];
 
         this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map((pair, i) => {
             const pos = this.getCalculatedPositions({ pair, index: i, collection: this.Document, docs: layoutDocs, state });
@@ -1075,7 +1074,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             for (const entry of array) {
                 const lastPos = this._cachedPool.get(entry[0]); // last computed pos
                 const newPos = entry[1];
-                if (!lastPos || newPos.x !== lastPos.x || newPos.y !== lastPos.y || newPos.z !== lastPos.z || newPos.zIndex !== lastPos.zIndex) {
+                if (!lastPos || newPos.opacity !== lastPos.opacity || newPos.x !== lastPos.x || newPos.y !== lastPos.y || newPos.z !== lastPos.z || newPos.zIndex !== lastPos.zIndex) {
                     this._layoutPoolData.set(entry[0], newPos);
                 }
                 if (!lastPos || newPos.height !== lastPos.height || newPos.width !== lastPos.width) {
@@ -1354,13 +1353,13 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             {!this.Document._LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ?
                 this.placeholder : this.marqueeView}
             <CollectionFreeFormOverlayView elements={this.elementFunc} />
-            {this.isAnnotationOverlay ? (null) :
+            {this.isAnnotationOverlay || !this.props.isSelected() ? (null) :
                 <>
                     <div key="back" className="backKeyframe" onClick={this.prevKeyframe}>
                         <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
                     </div>
                     <div key="num" className="numKeyframe" >
-                        {NumCast(this.props.Document.timecode)}
+                        {NumCast(this.props.Document.currentTimecode)}
                     </div>
                     <div key="fwd" className="fwdKeyframe" onClick={this.nextKeyframe}>
                         <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index c9bb543f1..5f0e28db2 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -36,11 +36,11 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         const rnd = seed / 233280;
         return min + rnd * (max - min);
     }
-    get displayName() { return "CollectionFreeFormDocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
+    get displayName() { return "CollectionFreeFormDocumentView(" + this.rootDoc.title + ")"; } // this makes mobx trace() statements more descriptive
     get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) rotate(${this.random(-1, 1) * this.props.jitterRotation}deg)`; }
     get X() { return this.dataProvider ? this.dataProvider.x : (this.Document.x || 0); }
     get Y() { return this.dataProvider ? this.dataProvider.y : (this.Document.y || 0); }
-    get Opacity() { return this.dataProvider ? this.dataProvider.opacity : (this.Document.opacity || 0); }
+    get Opacity() { return this.dataProvider ? this.dataProvider.opacity : Cast(this.layoutDoc.opacity, "number", null); }
     get ZInd() { return this.dataProvider ? this.dataProvider.zIndex : (this.Document.zIndex || 0); }
     get Highlight() { return this.dataProvider?.highlight; }
     get width() { return this.props.sizeProvider && this.sizeProvider ? this.sizeProvider.width : this.layoutDoc[WidthSym](); }
@@ -108,10 +108,10 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             (doc["x-indexed"] as any).push(NumCast(doc.x));
             (doc["y-indexed"] as any).push(NumCast(doc.y));
             (doc["opacity-indexed"] as any).push(NumCast(doc.opacity, 1));
-            doc.timecode = ComputedField.MakeFunction("collection.timecode", {}, { collection });
-            doc.x = ComputedField.MakeInterpolated("x", "timecode");
-            doc.y = ComputedField.MakeInterpolated("y", "timecode");
-            doc.opacity = ComputedField.MakeInterpolated("opacity", "timecode");
+            doc.displayTimecode = ComputedField.MakeFunction("collection ? collection.currentTimecode : 0", {}, { collection });
+            doc.x = ComputedField.MakeInterpolated("x", "displayTimecode");
+            doc.y = ComputedField.MakeInterpolated("y", "displayTimecode");
+            doc.opacity = ComputedField.MakeInterpolated("opacity", "displayTimecode");
         });
     }
 
@@ -125,6 +125,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     panelHeight = () => (this.sizeProvider?.height || this.props.PanelHeight?.());
     getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y).scale(1 / this.contentScaling());
     focusDoc = (doc: Doc) => this.props.focus(doc, false);
+    opacity = () => this.Opacity;
     NativeWidth = () => this.nativeWidth;
     NativeHeight = () => this.nativeHeight;
     render() {
@@ -144,7 +145,6 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                 transition: this.props.transition ? this.props.transition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.transition),
                 width: this.width,
                 height: this.height,
-                opacity: this.Opacity,
                 zIndex: this.ZInd,
                 display: this.ZInd === -99 ? "none" : undefined,
                 pointerEvents: this.props.Document.isBackground || this.Opacity === 0 ? "none" : this.props.pointerEvents ? "all" : undefined
@@ -164,6 +164,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                     ContentScaling={this.contentScaling}
                     ScreenToLocalTransform={this.getTransform}
                     backgroundColor={this.props.backgroundColor}
+                    opacity={this.opacity}
                     NativeHeight={this.NativeHeight}
                     NativeWidth={this.NativeWidth}
                     PanelWidth={this.panelWidth}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 2048be6fb..7bb945264 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -92,6 +92,7 @@ export interface DocumentViewProps {
     pinToPres: (document: Doc) => void;
     backgroundHalo?: () => boolean;
     backgroundColor?: (doc: Doc) => string | undefined;
+    opacity?: () => number;
     ChromeHeight?: () => number;
     dontRegisterView?: boolean;
     layoutKey?: string;
@@ -1119,6 +1120,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     render() {
         if (!(this.props.Document instanceof Doc)) return (null);
         const backgroundColor = Doc.UserDoc().renderStyle === "comic" ? undefined : StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document);
+        const opacity = Cast(this.layoutDoc._opacity, "number", Cast(this.layoutDoc.opacity, "number", Cast(this.Document.opacity, "number", null)));
+        const finalOpacity = this.props.opacity ? this.props.opacity() : opacity;
         const finalColor = this.layoutDoc.type === DocumentType.FONTICON || this.layoutDoc._viewType === CollectionViewType.Linear ? undefined : backgroundColor;
         const fullDegree = Doc.isBrushedHighlightedDegree(this.props.Document);
         const borderRounding = this.layoutDoc.borderRounding;
@@ -1155,7 +1158,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 border: highlighting && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined,
                 boxShadow: this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : undefined,
                 background: finalColor,
-                opacity: this.Document.opacity,
+                opacity: finalOpacity,
                 fontFamily: StrCast(this.Document._fontFamily, "inherit"),
                 fontSize: Cast(this.Document._fontSize, "number", null)
             }}>
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 342a8a215..6edcae417 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -5,7 +5,7 @@ import { observer } from "mobx-react";
 import { Doc, DocListCast, DocCastAsync } from "../../../fields/Doc";
 import { InkTool } from "../../../fields/InkField";
 import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
-import { returnFalse } from "../../../Utils";
+import { returnFalse, returnOne } from "../../../Utils";
 import { documentSchema } from "../../../fields/documentSchemas";
 import { DocumentManager } from "../../util/DocumentManager";
 import { undoBatch } from "../../util/UndoManager";
@@ -316,6 +316,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                         PanelWidth={this.props.PanelWidth}
                         PanelHeight={this.panelHeight}
                         moveDocument={returnFalse}
+                        childOpacity={returnOne}
                         childLayoutTemplate={this.childLayoutTemplate}
                         filterAddDocument={this.addDocumentFilter}
                         removeDocument={returnFalse}
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 280ba9093..26c8aa80a 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -177,6 +177,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     focus={emptyFunction}
                     whenActiveChanged={returnFalse}
                     bringToFront={returnFalse}
+                    opacity={returnOne}
                     ContainingCollectionView={undefined}
                     ContainingCollectionDoc={undefined}
                     ContentScaling={returnOne}
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index a1e1e11b1..9f38f4369 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -574,7 +574,7 @@ export namespace Doc {
                 if (field instanceof RefField) {
                     copy[key] = field;
                 } else if (cfield instanceof ComputedField) {
-                    copy[key] = ComputedField.MakeFunction(cfield.script.originalScript);
+                    copy[key] = cfield[Copy]();// ComputedField.MakeFunction(cfield.script.originalScript);
                 } else if (field instanceof ObjectField) {
                     copy[key] = doc[key] instanceof Doc ?
                         key.includes("layout[") ? Doc.MakeCopy(doc[key] as Doc, false) : doc[key] : // reference documents except copy documents that are expanded teplate fields 
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index 0ac1ac360..3a4cdbdf8 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -140,10 +140,14 @@ export class ComputedField extends ScriptField {
     _valueOutsideReaction = (doc: Doc) => this._lastComputedResult = this.script.run({ this: doc, self: Cast(doc.rootDocument, Doc, null) || doc, _last_: this._lastComputedResult }, console.log).result;
 
 
+    [Copy](): ObjectField {
+        return new ComputedField(this.script);
+    }
+
     constructor(script: CompiledScript, setterscript?: CompiledScript) {
         super(script,
-            !setterscript && script?.originalScript.includes("self.timecode") ?
-                ScriptField.CompileScript("self['x' + self.timecode] = value", { value: "any" }, true) : setterscript);
+            !setterscript && script?.originalScript.includes("self.displayTimecode") ?
+                ScriptField.CompileScript("self['x' + self.displayTimecode] = value", { value: "any" }, true) : setterscript);
     }
 
     public static MakeScript(script: string, params: object = {}) {
-- 
cgit v1.2.3-70-g09d2


From beece97c0645b1466b2c4210b594220b84953e04 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 18 May 2020 15:37:57 -0400
Subject: added a button to copy a workspace

---
 src/client/views/MainView.tsx                          | 18 +++++++++++++-----
 .../collectionFreeForm/CollectionFreeFormView.tsx      |  2 --
 src/client/views/nodes/DocumentView.tsx                |  2 +-
 3 files changed, 14 insertions(+), 8 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 4a20c39d4..1d6421656 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -186,16 +186,17 @@ export class MainView extends React.Component {
             _LODdisable: true
         };
         const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
-        const mainDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [Doc.UserDoc().myCatalog as Doc] }], { title: `Workspace ${workspaceCount}` }, id, "row");
+        const workspaceDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [Doc.UserDoc().myCatalog as Doc] }], { title: `Workspace ${workspaceCount}` }, id, "row");
 
         const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`);
         const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
-        mainDoc.contextMenuScripts = new List<ScriptField>([toggleTheme!, toggleComic!]);
-        mainDoc.contextMenuLabels = new List<string>(["Toggle Theme Colors", "Toggle Comic Mode"]);
+        const cloneWorkspace = ScriptField.MakeScript(`cloneWorkspace()`);
+        workspaceDoc.contextMenuScripts = new List<ScriptField>([toggleTheme!, toggleComic!, cloneWorkspace!]);
+        workspaceDoc.contextMenuLabels = new List<string>(["Toggle Theme Colors", "Toggle Comic Mode", "New Workspace Layout"]);
 
-        Doc.AddDocToList(workspaces, "data", mainDoc);
+        Doc.AddDocToList(workspaces, "data", workspaceDoc);
         // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
-        setTimeout(() => this.openWorkspace(mainDoc), 0);
+        setTimeout(() => this.openWorkspace(workspaceDoc), 0);
     }
 
     @action
@@ -564,3 +565,10 @@ export class MainView extends React.Component {
 }
 Scripting.addGlobal(function freezeSidebar() { MainView.expandFlyout(); });
 Scripting.addGlobal(function toggleComicMode() { Doc.UserDoc().fontFamily = "Comic Sans MS"; Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic" });
+Scripting.addGlobal(function cloneWorkspace() {
+    const copiedWorkspace = Doc.MakeCopy(Cast(Doc.UserDoc().activeWorkspace, Doc, null), true);
+    const workspaces = Cast(Doc.UserDoc().myWorkspaces, Doc, null);
+    Doc.AddDocToList(workspaces, "data", copiedWorkspace);
+    // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
+    setTimeout(() => MainView.Instance.openWorkspace(copiedWorkspace), 0);
+});
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index d8fe662ae..aeb0a5813 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1179,8 +1179,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                 this._timelineVisible = !this._timelineVisible;
             }), icon: this._timelineVisible ? faEyeSlash : faEye
         });
-        ContextMenu.Instance.addItem({ description: "Advance", event: this.nextKeyframe, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" });
-        ContextMenu.Instance.addItem({ description: "Backup ", event: this.prevKeyframe, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" });
 
         const options = ContextMenu.Instance.findByDescription("Options...");
         const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 7bb945264..b9d33da90 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1167,7 +1167,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 <div className="documentView-contentBlocker" />
             </> :
                 this.innards}
-            {(this.Document.isBackground !== undefined || this.isSelected(false)) && this.props.renderDepth > 0 && this.props.PanelWidth() > 0 ?
+            {(this.Document.isBackground !== undefined || this.isSelected(false)) && (this.Document.type === DocumentType.COL || this.Document.type === DocumentType.IMG) && this.props.renderDepth > 0 && this.props.PanelWidth() > 0 ?
                 <div className="documentView-lock" onClick={() => this.toggleBackground(true)}>
                     <FontAwesomeIcon icon={this.Document.isBackground ? "unlock" : "lock"} style={{ color: this.Document.isBackground ? "red" : undefined }} size="lg" />
                 </div>
-- 
cgit v1.2.3-70-g09d2


From 5eb598ecd1da85d8c18f9f7cb3b795bae280b3de Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 18 May 2020 19:46:23 -0400
Subject: added opacity for stacking views.

---
 package-lock.json                                  | 872 ++++++++++-----------
 .../views/collections/CollectionStackingView.tsx   |   5 +-
 src/client/views/collections/CollectionView.tsx    |   2 +-
 src/client/views/nodes/DocumentView.tsx            |   2 +-
 4 files changed, 431 insertions(+), 450 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/package-lock.json b/package-lock.json
index a0dd255af..9f9db7cfc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2917,8 +2917,7 @@
                         },
                         "ansi-regex": {
                             "version": "2.1.1",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "aproba": {
                             "version": "1.2.0",
@@ -2936,13 +2935,11 @@
                         },
                         "balanced-match": {
                             "version": "1.0.0",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "brace-expansion": {
                             "version": "1.1.11",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "balanced-match": "^1.0.0",
                                 "concat-map": "0.0.1"
@@ -2955,18 +2952,15 @@
                         },
                         "code-point-at": {
                             "version": "1.1.0",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "concat-map": {
                             "version": "0.0.1",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "console-control-strings": {
                             "version": "1.1.0",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "core-util-is": {
                             "version": "1.0.2",
@@ -3069,8 +3063,7 @@
                         },
                         "inherits": {
                             "version": "2.0.4",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "ini": {
                             "version": "1.3.5",
@@ -3080,7 +3073,6 @@
                         "is-fullwidth-code-point": {
                             "version": "1.0.0",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "number-is-nan": "^1.0.0"
                             }
@@ -3093,20 +3085,17 @@
                         "minimatch": {
                             "version": "3.0.4",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "brace-expansion": "^1.1.7"
                             }
                         },
                         "minimist": {
                             "version": "1.2.5",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "minipass": {
                             "version": "2.9.0",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "safe-buffer": "^5.1.2",
                                 "yallist": "^3.0.0"
@@ -3123,7 +3112,6 @@
                         "mkdirp": {
                             "version": "0.5.3",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "minimist": "^1.2.5"
                             }
@@ -3179,8 +3167,7 @@
                         },
                         "npm-normalize-package-bin": {
                             "version": "1.0.1",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "npm-packlist": {
                             "version": "1.4.8",
@@ -3205,8 +3192,7 @@
                         },
                         "number-is-nan": {
                             "version": "1.0.1",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "object-assign": {
                             "version": "4.1.1",
@@ -3216,7 +3202,6 @@
                         "once": {
                             "version": "1.4.0",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "wrappy": "1"
                             }
@@ -3285,8 +3270,7 @@
                         },
                         "safe-buffer": {
                             "version": "5.1.2",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "safer-buffer": {
                             "version": "2.1.2",
@@ -3316,7 +3300,6 @@
                         "string-width": {
                             "version": "1.0.2",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "code-point-at": "^1.0.0",
                                 "is-fullwidth-code-point": "^1.0.0",
@@ -3334,7 +3317,6 @@
                         "strip-ansi": {
                             "version": "3.0.1",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "ansi-regex": "^2.0.0"
                             }
@@ -3373,13 +3355,11 @@
                         },
                         "wrappy": {
                             "version": "1.0.2",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "yallist": {
                             "version": "3.1.1",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         }
                     }
                 }
@@ -9548,7 +9528,7 @@
             "dependencies": {
                 "JSONStream": {
                     "version": "1.3.5",
-                    "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+                    "resolved": false,
                     "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
                     "requires": {
                         "jsonparse": "^1.2.0",
@@ -9557,12 +9537,12 @@
                 },
                 "abbrev": {
                     "version": "1.1.1",
-                    "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
                 },
                 "agent-base": {
                     "version": "4.3.0",
-                    "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
                     "requires": {
                         "es6-promisify": "^5.0.0"
@@ -9570,7 +9550,7 @@
                 },
                 "agentkeepalive": {
                     "version": "3.5.2",
-                    "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==",
                     "requires": {
                         "humanize-ms": "^1.2.1"
@@ -9578,7 +9558,7 @@
                 },
                 "ajv": {
                     "version": "5.5.2",
-                    "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
                     "requires": {
                         "co": "^4.6.0",
@@ -9589,7 +9569,7 @@
                 },
                 "ansi-align": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
                     "requires": {
                         "string-width": "^2.0.0"
@@ -9597,12 +9577,12 @@
                 },
                 "ansi-regex": {
                     "version": "2.1.1",
-                    "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
                 },
                 "ansi-styles": {
                     "version": "3.2.1",
-                    "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
                         "color-convert": "^1.9.0"
@@ -9610,27 +9590,27 @@
                 },
                 "ansicolors": {
                     "version": "0.3.2",
-                    "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk="
                 },
                 "ansistyles": {
                     "version": "0.1.3",
-                    "resolved": "https://registry.npmjs.org/ansistyles/-/ansistyles-0.1.3.tgz",
+                    "resolved": false,
                     "integrity": "sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk="
                 },
                 "aproba": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
                 },
                 "archy": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA="
                 },
                 "are-we-there-yet": {
                     "version": "1.1.4",
-                    "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
+                    "resolved": false,
                     "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
                     "requires": {
                         "delegates": "^1.0.0",
@@ -9639,7 +9619,7 @@
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
-                            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+                            "resolved": false,
                             "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
                             "requires": {
                                 "core-util-is": "~1.0.0",
@@ -9653,7 +9633,7 @@
                         },
                         "string_decoder": {
                             "version": "1.1.1",
-                            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+                            "resolved": false,
                             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
                             "requires": {
                                 "safe-buffer": "~5.1.0"
@@ -9663,12 +9643,12 @@
                 },
                 "asap": {
                     "version": "2.0.6",
-                    "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+                    "resolved": false,
                     "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
                 },
                 "asn1": {
                     "version": "0.2.4",
-                    "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
                     "requires": {
                         "safer-buffer": "~2.1.0"
@@ -9676,32 +9656,32 @@
                 },
                 "assert-plus": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
                 },
                 "asynckit": {
                     "version": "0.4.0",
-                    "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
                 },
                 "aws-sign2": {
                     "version": "0.7.0",
-                    "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
                 },
                 "aws4": {
                     "version": "1.8.0",
-                    "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
                 },
                 "balanced-match": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
                 },
                 "bcrypt-pbkdf": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
                     "optional": true,
                     "requires": {
@@ -9710,7 +9690,7 @@
                 },
                 "bin-links": {
                     "version": "1.1.7",
-                    "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-1.1.7.tgz",
+                    "resolved": false,
                     "integrity": "sha512-/eaLaTu7G7/o7PV04QPy1HRT65zf+1tFkPGv0sPTV0tRwufooYBQO3zrcyGgm+ja+ZtBf2GEuKjDRJ2pPG+yqA==",
                     "requires": {
                         "bluebird": "^3.5.3",
@@ -9723,12 +9703,12 @@
                 },
                 "bluebird": {
                     "version": "3.5.5",
-                    "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
+                    "resolved": false,
                     "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w=="
                 },
                 "boxen": {
                     "version": "1.3.0",
-                    "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
                     "requires": {
                         "ansi-align": "^2.0.0",
@@ -9742,7 +9722,7 @@
                 },
                 "brace-expansion": {
                     "version": "1.1.11",
-                    "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+                    "resolved": false,
                     "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
                     "requires": {
                         "balanced-match": "^1.0.0",
@@ -9751,27 +9731,27 @@
                 },
                 "buffer-from": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA=="
                 },
                 "builtins": {
                     "version": "1.0.3",
-                    "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og="
                 },
                 "byline": {
                     "version": "5.0.0",
-                    "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE="
                 },
                 "byte-size": {
                     "version": "5.0.1",
-                    "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-5.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-/XuKeqWocKsYa/cBY1YbSJSWWqTi4cFgr9S6OyM7PBaPbr9zvNGwWP33vt0uqGhwDdN+y3yhbXVILEUpnwEWGw=="
                 },
                 "cacache": {
                     "version": "12.0.3",
-                    "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==",
                     "requires": {
                         "bluebird": "^3.5.5",
@@ -9793,27 +9773,27 @@
                 },
                 "call-limit": {
                     "version": "1.1.1",
-                    "resolved": "https://registry.npmjs.org/call-limit/-/call-limit-1.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-5twvci5b9eRBw2wCfPtN0GmlR2/gadZqyFpPhOK6CvMFoFgA+USnZ6Jpu1lhG9h85pQ3Ouil3PfXWRD4EUaRiQ=="
                 },
                 "camelcase": {
                     "version": "4.1.0",
-                    "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
                 },
                 "capture-stack-trace": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0="
                 },
                 "caseless": {
                     "version": "0.12.0",
-                    "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
                 },
                 "chalk": {
                     "version": "2.4.1",
-                    "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
                     "requires": {
                         "ansi-styles": "^3.2.1",
@@ -9828,12 +9808,12 @@
                 },
                 "ci-info": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="
                 },
                 "cidr-regex": {
                     "version": "2.0.10",
-                    "resolved": "https://registry.npmjs.org/cidr-regex/-/cidr-regex-2.0.10.tgz",
+                    "resolved": false,
                     "integrity": "sha512-sB3ogMQXWvreNPbJUZMRApxuRYd+KoIo4RGQ81VatjmMW6WJPo+IJZ2846FGItr9VzKo5w7DXzijPLGtSd0N3Q==",
                     "requires": {
                         "ip-regex": "^2.1.0"
@@ -9841,12 +9821,12 @@
                 },
                 "cli-boxes": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM="
                 },
                 "cli-columns": {
                     "version": "3.1.2",
-                    "resolved": "https://registry.npmjs.org/cli-columns/-/cli-columns-3.1.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-ZzLZcpee/CrkRKHwjgj6E5yWoY4=",
                     "requires": {
                         "string-width": "^2.0.0",
@@ -9855,7 +9835,7 @@
                 },
                 "cli-table3": {
                     "version": "0.5.1",
-                    "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==",
                     "requires": {
                         "colors": "^1.1.2",
@@ -9865,7 +9845,7 @@
                 },
                 "cliui": {
                     "version": "4.1.0",
-                    "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
                     "requires": {
                         "string-width": "^2.1.1",
@@ -9875,12 +9855,12 @@
                     "dependencies": {
                         "ansi-regex": {
                             "version": "3.0.0",
-                            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+                            "resolved": false,
                             "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
                         },
                         "strip-ansi": {
                             "version": "4.0.0",
-                            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+                            "resolved": false,
                             "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                             "requires": {
                                 "ansi-regex": "^3.0.0"
@@ -9890,12 +9870,12 @@
                 },
                 "clone": {
                     "version": "1.0.4",
-                    "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+                    "resolved": false,
                     "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4="
                 },
                 "cmd-shim": {
                     "version": "3.0.3",
-                    "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-3.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-DtGg+0xiFhQIntSBRzL2fRQBnmtAVwXIDo4Qq46HPpObYquxMaZS4sb82U9nH91qJrlosC1wa9gwr0QyL/HypA==",
                     "requires": {
                         "graceful-fs": "^4.1.2",
@@ -9904,17 +9884,17 @@
                 },
                 "co": {
                     "version": "4.6.0",
-                    "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
                 },
                 "code-point-at": {
                     "version": "1.1.0",
-                    "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
                 },
                 "color-convert": {
                     "version": "1.9.1",
-                    "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
                     "requires": {
                         "color-name": "^1.1.1"
@@ -9922,18 +9902,18 @@
                 },
                 "color-name": {
                     "version": "1.1.3",
-                    "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+                    "resolved": false,
                     "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
                 },
                 "colors": {
                     "version": "1.3.3",
-                    "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==",
                     "optional": true
                 },
                 "columnify": {
                     "version": "1.5.4",
-                    "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz",
+                    "resolved": false,
                     "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=",
                     "requires": {
                         "strip-ansi": "^3.0.0",
@@ -9942,7 +9922,7 @@
                 },
                 "combined-stream": {
                     "version": "1.0.6",
-                    "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
+                    "resolved": false,
                     "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
                     "requires": {
                         "delayed-stream": "~1.0.0"
@@ -9950,12 +9930,12 @@
                 },
                 "concat-map": {
                     "version": "0.0.1",
-                    "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
                 },
                 "concat-stream": {
                     "version": "1.6.2",
-                    "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
                     "requires": {
                         "buffer-from": "^1.0.0",
@@ -9966,7 +9946,7 @@
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
-                            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+                            "resolved": false,
                             "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
                             "requires": {
                                 "core-util-is": "~1.0.0",
@@ -9980,7 +9960,7 @@
                         },
                         "string_decoder": {
                             "version": "1.1.1",
-                            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+                            "resolved": false,
                             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
                             "requires": {
                                 "safe-buffer": "~5.1.0"
@@ -9990,7 +9970,7 @@
                 },
                 "config-chain": {
                     "version": "1.1.12",
-                    "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz",
+                    "resolved": false,
                     "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
                     "requires": {
                         "ini": "^1.3.4",
@@ -9999,7 +9979,7 @@
                 },
                 "configstore": {
                     "version": "3.1.2",
-                    "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==",
                     "requires": {
                         "dot-prop": "^4.1.0",
@@ -10012,12 +9992,12 @@
                 },
                 "console-control-strings": {
                     "version": "1.1.0",
-                    "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
                 },
                 "copy-concurrently": {
                     "version": "1.0.5",
-                    "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
+                    "resolved": false,
                     "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
                     "requires": {
                         "aproba": "^1.1.1",
@@ -10030,24 +10010,24 @@
                     "dependencies": {
                         "aproba": {
                             "version": "1.2.0",
-                            "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
                         },
                         "iferr": {
                             "version": "0.1.5",
-                            "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+                            "resolved": false,
                             "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE="
                         }
                     }
                 },
                 "core-util-is": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
                 },
                 "create-error-class": {
                     "version": "3.0.2",
-                    "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
                     "requires": {
                         "capture-stack-trace": "^1.0.0"
@@ -10055,7 +10035,7 @@
                 },
                 "cross-spawn": {
                     "version": "5.1.0",
-                    "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
                     "requires": {
                         "lru-cache": "^4.0.1",
@@ -10065,7 +10045,7 @@
                     "dependencies": {
                         "lru-cache": {
                             "version": "4.1.5",
-                            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+                            "resolved": false,
                             "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
                             "requires": {
                                 "pseudomap": "^1.0.2",
@@ -10074,24 +10054,24 @@
                         },
                         "yallist": {
                             "version": "2.1.2",
-                            "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+                            "resolved": false,
                             "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
                         }
                     }
                 },
                 "crypto-random-string": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4="
                 },
                 "cyclist": {
                     "version": "0.2.2",
-                    "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA="
                 },
                 "dashdash": {
                     "version": "1.14.1",
-                    "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
                     "requires": {
                         "assert-plus": "^1.0.0"
@@ -10099,7 +10079,7 @@
                 },
                 "debug": {
                     "version": "3.1.0",
-                    "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
                     "requires": {
                         "ms": "2.0.0"
@@ -10107,24 +10087,24 @@
                     "dependencies": {
                         "ms": {
                             "version": "2.0.0",
-                            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+                            "resolved": false,
                             "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
                         }
                     }
                 },
                 "debuglog": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI="
                 },
                 "decamelize": {
                     "version": "1.2.0",
-                    "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
                 },
                 "decode-uri-component": {
                     "version": "0.2.0",
-                    "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
                 },
                 "deep-extend": {
@@ -10134,7 +10114,7 @@
                 },
                 "defaults": {
                     "version": "1.0.3",
-                    "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
                     "requires": {
                         "clone": "^1.0.2"
@@ -10142,7 +10122,7 @@
                 },
                 "define-properties": {
                     "version": "1.1.3",
-                    "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
                     "requires": {
                         "object-keys": "^1.0.12"
@@ -10150,27 +10130,27 @@
                 },
                 "delayed-stream": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
                 },
                 "delegates": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
                 },
                 "detect-indent": {
                     "version": "5.0.0",
-                    "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50="
                 },
                 "detect-newline": {
                     "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I="
                 },
                 "dezalgo": {
                     "version": "1.0.3",
-                    "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=",
                     "requires": {
                         "asap": "^2.0.0",
@@ -10179,7 +10159,7 @@
                 },
                 "dot-prop": {
                     "version": "4.2.0",
-                    "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
                     "requires": {
                         "is-obj": "^1.0.0"
@@ -10187,17 +10167,17 @@
                 },
                 "dotenv": {
                     "version": "5.0.1",
-                    "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow=="
                 },
                 "duplexer3": {
                     "version": "0.1.4",
-                    "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+                    "resolved": false,
                     "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
                 },
                 "duplexify": {
                     "version": "3.6.0",
-                    "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==",
                     "requires": {
                         "end-of-stream": "^1.0.0",
@@ -10208,7 +10188,7 @@
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
-                            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+                            "resolved": false,
                             "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
                             "requires": {
                                 "core-util-is": "~1.0.0",
@@ -10222,7 +10202,7 @@
                         },
                         "string_decoder": {
                             "version": "1.1.1",
-                            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+                            "resolved": false,
                             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
                             "requires": {
                                 "safe-buffer": "~5.1.0"
@@ -10232,7 +10212,7 @@
                 },
                 "ecc-jsbn": {
                     "version": "0.1.2",
-                    "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
                     "optional": true,
                     "requires": {
@@ -10242,12 +10222,12 @@
                 },
                 "editor": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/editor/-/editor-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-YMf4e9YrzGqJT6jM1q+3gjok90I="
                 },
                 "encoding": {
                     "version": "0.1.12",
-                    "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
+                    "resolved": false,
                     "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
                     "requires": {
                         "iconv-lite": "~0.4.13"
@@ -10255,7 +10235,7 @@
                 },
                 "end-of-stream": {
                     "version": "1.4.1",
-                    "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
                     "requires": {
                         "once": "^1.4.0"
@@ -10263,17 +10243,17 @@
                 },
                 "env-paths": {
                     "version": "2.2.0",
-                    "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA=="
                 },
                 "err-code": {
                     "version": "1.1.2",
-                    "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA="
                 },
                 "errno": {
                     "version": "0.1.7",
-                    "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+                    "resolved": false,
                     "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
                     "requires": {
                         "prr": "~1.0.1"
@@ -10281,7 +10261,7 @@
                 },
                 "es-abstract": {
                     "version": "1.12.0",
-                    "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
                     "requires": {
                         "es-to-primitive": "^1.1.1",
@@ -10293,7 +10273,7 @@
                 },
                 "es-to-primitive": {
                     "version": "1.2.0",
-                    "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
                     "requires": {
                         "is-callable": "^1.1.4",
@@ -10303,12 +10283,12 @@
                 },
                 "es6-promise": {
                     "version": "4.2.8",
-                    "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
+                    "resolved": false,
                     "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
                 },
                 "es6-promisify": {
                     "version": "5.0.0",
-                    "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
                     "requires": {
                         "es6-promise": "^4.0.3"
@@ -10316,12 +10296,12 @@
                 },
                 "escape-string-regexp": {
                     "version": "1.0.5",
-                    "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+                    "resolved": false,
                     "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
                 },
                 "execa": {
                     "version": "0.7.0",
-                    "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
                     "requires": {
                         "cross-spawn": "^5.0.1",
@@ -10335,44 +10315,44 @@
                     "dependencies": {
                         "get-stream": {
                             "version": "3.0.0",
-                            "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+                            "resolved": false,
                             "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
                         }
                     }
                 },
                 "extend": {
                     "version": "3.0.2",
-                    "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
                 },
                 "extsprintf": {
                     "version": "1.3.0",
-                    "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
                 },
                 "fast-deep-equal": {
                     "version": "1.1.0",
-                    "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
                 },
                 "fast-json-stable-stringify": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
                 },
                 "figgy-pudding": {
                     "version": "3.5.1",
-                    "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w=="
                 },
                 "find-npm-prefix": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA=="
                 },
                 "find-up": {
                     "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
                     "requires": {
                         "locate-path": "^2.0.0"
@@ -10380,7 +10360,7 @@
                 },
                 "flush-write-stream": {
                     "version": "1.0.3",
-                    "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==",
                     "requires": {
                         "inherits": "^2.0.1",
@@ -10389,7 +10369,7 @@
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
-                            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+                            "resolved": false,
                             "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
                             "requires": {
                                 "core-util-is": "~1.0.0",
@@ -10403,7 +10383,7 @@
                         },
                         "string_decoder": {
                             "version": "1.1.1",
-                            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+                            "resolved": false,
                             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
                             "requires": {
                                 "safe-buffer": "~5.1.0"
@@ -10413,12 +10393,12 @@
                 },
                 "forever-agent": {
                     "version": "0.6.1",
-                    "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
                 },
                 "form-data": {
                     "version": "2.3.2",
-                    "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
                     "requires": {
                         "asynckit": "^0.4.0",
@@ -10428,7 +10408,7 @@
                 },
                 "from2": {
                     "version": "2.3.0",
-                    "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
                     "requires": {
                         "inherits": "^2.0.1",
@@ -10437,7 +10417,7 @@
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
-                            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+                            "resolved": false,
                             "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
                             "requires": {
                                 "core-util-is": "~1.0.0",
@@ -10451,7 +10431,7 @@
                         },
                         "string_decoder": {
                             "version": "1.1.1",
-                            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+                            "resolved": false,
                             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
                             "requires": {
                                 "safe-buffer": "~5.1.0"
@@ -10461,7 +10441,7 @@
                 },
                 "fs-minipass": {
                     "version": "1.2.7",
-                    "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
+                    "resolved": false,
                     "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
                     "requires": {
                         "minipass": "^2.6.0"
@@ -10469,7 +10449,7 @@
                     "dependencies": {
                         "minipass": {
                             "version": "2.9.0",
-                            "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
                             "requires": {
                                 "safe-buffer": "^5.1.2",
@@ -10480,7 +10460,7 @@
                 },
                 "fs-vacuum": {
                     "version": "1.2.10",
-                    "resolved": "https://registry.npmjs.org/fs-vacuum/-/fs-vacuum-1.2.10.tgz",
+                    "resolved": false,
                     "integrity": "sha1-t2Kb7AekAxolSP35n17PHMizHjY=",
                     "requires": {
                         "graceful-fs": "^4.1.2",
@@ -10490,7 +10470,7 @@
                 },
                 "fs-write-stream-atomic": {
                     "version": "1.0.10",
-                    "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+                    "resolved": false,
                     "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
                     "requires": {
                         "graceful-fs": "^4.1.2",
@@ -10501,12 +10481,12 @@
                     "dependencies": {
                         "iferr": {
                             "version": "0.1.5",
-                            "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+                            "resolved": false,
                             "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE="
                         },
                         "readable-stream": {
                             "version": "2.3.6",
-                            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+                            "resolved": false,
                             "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
                             "requires": {
                                 "core-util-is": "~1.0.0",
@@ -10520,7 +10500,7 @@
                         },
                         "string_decoder": {
                             "version": "1.1.1",
-                            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+                            "resolved": false,
                             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
                             "requires": {
                                 "safe-buffer": "~5.1.0"
@@ -10530,17 +10510,17 @@
                 },
                 "fs.realpath": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
                 },
                 "function-bind": {
                     "version": "1.1.1",
-                    "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
                 },
                 "gauge": {
                     "version": "2.7.4",
-                    "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+                    "resolved": false,
                     "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
                     "requires": {
                         "aproba": "^1.0.3",
@@ -10555,12 +10535,12 @@
                     "dependencies": {
                         "aproba": {
                             "version": "1.2.0",
-                            "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
                         },
                         "string-width": {
                             "version": "1.0.2",
-                            "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+                            "resolved": false,
                             "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
                             "requires": {
                                 "code-point-at": "^1.0.0",
@@ -10572,12 +10552,12 @@
                 },
                 "genfun": {
                     "version": "5.0.0",
-                    "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA=="
                 },
                 "gentle-fs": {
                     "version": "2.3.0",
-                    "resolved": "https://registry.npmjs.org/gentle-fs/-/gentle-fs-2.3.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-3k2CgAmPxuz7S6nKK+AqFE2AdM1QuwqKLPKzIET3VRwK++3q96MsNFobScDjlCrq97ZJ8y5R725MOlm6ffUCjg==",
                     "requires": {
                         "aproba": "^1.1.2",
@@ -10595,24 +10575,24 @@
                     "dependencies": {
                         "aproba": {
                             "version": "1.2.0",
-                            "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
                         },
                         "iferr": {
                             "version": "0.1.5",
-                            "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+                            "resolved": false,
                             "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE="
                         }
                     }
                 },
                 "get-caller-file": {
                     "version": "1.0.3",
-                    "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="
                 },
                 "get-stream": {
                     "version": "4.1.0",
-                    "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
                     "requires": {
                         "pump": "^3.0.0"
@@ -10620,7 +10600,7 @@
                 },
                 "getpass": {
                     "version": "0.1.7",
-                    "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+                    "resolved": false,
                     "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
                     "requires": {
                         "assert-plus": "^1.0.0"
@@ -10641,7 +10621,7 @@
                 },
                 "global-dirs": {
                     "version": "0.1.1",
-                    "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
                     "requires": {
                         "ini": "^1.3.4"
@@ -10649,7 +10629,7 @@
                 },
                 "got": {
                     "version": "6.7.1",
-                    "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
                     "requires": {
                         "create-error-class": "^3.0.0",
@@ -10667,24 +10647,24 @@
                     "dependencies": {
                         "get-stream": {
                             "version": "3.0.0",
-                            "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+                            "resolved": false,
                             "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
                         }
                     }
                 },
                 "graceful-fs": {
                     "version": "4.2.3",
-                    "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
                 },
                 "har-schema": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
                 },
                 "har-validator": {
                     "version": "5.1.0",
-                    "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==",
                     "requires": {
                         "ajv": "^5.3.0",
@@ -10693,7 +10673,7 @@
                 },
                 "has": {
                     "version": "1.0.3",
-                    "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
                     "requires": {
                         "function-bind": "^1.1.1"
@@ -10701,17 +10681,17 @@
                 },
                 "has-flag": {
                     "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
                 },
                 "has-symbols": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q="
                 },
                 "has-unicode": {
                     "version": "2.0.1",
-                    "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
                 },
                 "hosted-git-info": {
@@ -10721,12 +10701,12 @@
                 },
                 "http-cache-semantics": {
                     "version": "3.8.1",
-                    "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w=="
                 },
                 "http-proxy-agent": {
                     "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
                     "requires": {
                         "agent-base": "4",
@@ -10735,7 +10715,7 @@
                 },
                 "http-signature": {
                     "version": "1.2.0",
-                    "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
                     "requires": {
                         "assert-plus": "^1.0.0",
@@ -10745,7 +10725,7 @@
                 },
                 "https-proxy-agent": {
                     "version": "2.2.4",
-                    "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
                     "requires": {
                         "agent-base": "^4.3.0",
@@ -10754,7 +10734,7 @@
                 },
                 "humanize-ms": {
                     "version": "1.2.1",
-                    "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
                     "requires": {
                         "ms": "^2.0.0"
@@ -10762,7 +10742,7 @@
                 },
                 "iconv-lite": {
                     "version": "0.4.23",
-                    "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
+                    "resolved": false,
                     "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
                     "requires": {
                         "safer-buffer": ">= 2.1.2 < 3"
@@ -10770,12 +10750,12 @@
                 },
                 "iferr": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/iferr/-/iferr-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-9AfeLfji44r5TKInjhz3W9DyZI1zR1JAf2hVBMGhddAKPqBsupb89jGfbCTHIGZd6fGZl9WlHdn4AObygyMKwg=="
                 },
                 "ignore-walk": {
                     "version": "3.0.3",
-                    "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
                     "requires": {
                         "minimatch": "^3.0.4"
@@ -10783,22 +10763,22 @@
                 },
                 "import-lazy": {
                     "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM="
                 },
                 "imurmurhash": {
                     "version": "0.1.4",
-                    "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+                    "resolved": false,
                     "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
                 },
                 "infer-owner": {
                     "version": "1.0.4",
-                    "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="
                 },
                 "inflight": {
                     "version": "1.0.6",
-                    "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+                    "resolved": false,
                     "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
                     "requires": {
                         "once": "^1.3.0",
@@ -10807,17 +10787,17 @@
                 },
                 "inherits": {
                     "version": "2.0.4",
-                    "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
                 },
                 "ini": {
                     "version": "1.3.5",
-                    "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+                    "resolved": false,
                     "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
                 },
                 "init-package-json": {
                     "version": "1.10.3",
-                    "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-1.10.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-zKSiXKhQveNteyhcj1CoOP8tqp1QuxPIPBl8Bid99DGLFqA1p87M6lNgfjJHSBoWJJlidGOv5rWjyYKEB3g2Jw==",
                     "requires": {
                         "glob": "^7.1.1",
@@ -10832,22 +10812,22 @@
                 },
                 "invert-kv": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA=="
                 },
                 "ip": {
                     "version": "1.1.5",
-                    "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+                    "resolved": false,
                     "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
                 },
                 "ip-regex": {
                     "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk="
                 },
                 "is-callable": {
                     "version": "1.1.4",
-                    "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
                 },
                 "is-ci": {
@@ -10860,14 +10840,14 @@
                     "dependencies": {
                         "ci-info": {
                             "version": "1.6.0",
-                            "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A=="
                         }
                     }
                 },
                 "is-cidr": {
                     "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/is-cidr/-/is-cidr-3.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-8Xnnbjsb0x462VoYiGlhEi+drY8SFwrHiSYuzc/CEwco55vkehTaxAyIjEdpi3EMvLPPJAJi9FlzP+h+03gp0Q==",
                     "requires": {
                         "cidr-regex": "^2.0.10"
@@ -10875,12 +10855,12 @@
                 },
                 "is-date-object": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY="
                 },
                 "is-fullwidth-code-point": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
                     "requires": {
                         "number-is-nan": "^1.0.0"
@@ -10888,7 +10868,7 @@
                 },
                 "is-installed-globally": {
                     "version": "0.1.0",
-                    "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
                     "requires": {
                         "global-dirs": "^0.1.0",
@@ -10897,17 +10877,17 @@
                 },
                 "is-npm": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ="
                 },
                 "is-obj": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
                 },
                 "is-path-inside": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
                     "requires": {
                         "path-is-inside": "^1.0.1"
@@ -10915,12 +10895,12 @@
                 },
                 "is-redirect": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ="
                 },
                 "is-regex": {
                     "version": "1.0.4",
-                    "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+                    "resolved": false,
                     "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
                     "requires": {
                         "has": "^1.0.1"
@@ -10933,12 +10913,12 @@
                 },
                 "is-stream": {
                     "version": "1.1.0",
-                    "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
                 },
                 "is-symbol": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
                     "requires": {
                         "has-symbols": "^1.0.0"
@@ -10946,58 +10926,58 @@
                 },
                 "is-typedarray": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
                 },
                 "isarray": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
                 },
                 "isexe": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
                 },
                 "isstream": {
                     "version": "0.1.2",
-                    "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
                 },
                 "jsbn": {
                     "version": "0.1.1",
-                    "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
                     "optional": true
                 },
                 "json-parse-better-errors": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
                 },
                 "json-schema": {
                     "version": "0.2.3",
-                    "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+                    "resolved": false,
                     "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
                 },
                 "json-schema-traverse": {
                     "version": "0.3.1",
-                    "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
                 },
                 "json-stringify-safe": {
                     "version": "5.0.1",
-                    "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
                 },
                 "jsonparse": {
                     "version": "1.3.1",
-                    "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA="
                 },
                 "jsprim": {
                     "version": "1.4.1",
-                    "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
                     "requires": {
                         "assert-plus": "1.0.0",
@@ -11008,7 +10988,7 @@
                 },
                 "latest-version": {
                     "version": "3.1.0",
-                    "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
                     "requires": {
                         "package-json": "^4.0.0"
@@ -11016,12 +10996,12 @@
                 },
                 "lazy-property": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/lazy-property/-/lazy-property-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-hN3Es3Bnm6i9TNz6TAa0PVcREUc="
                 },
                 "lcid": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
                     "requires": {
                         "invert-kv": "^2.0.0"
@@ -11029,7 +11009,7 @@
                 },
                 "libcipm": {
                     "version": "4.0.7",
-                    "resolved": "https://registry.npmjs.org/libcipm/-/libcipm-4.0.7.tgz",
+                    "resolved": false,
                     "integrity": "sha512-fTq33otU3PNXxxCTCYCYe7V96o59v/o7bvtspmbORXpgFk+wcWrGf5x6tBgui5gCed/45/wtPomBsZBYm5KbIw==",
                     "requires": {
                         "bin-links": "^1.1.2",
@@ -11051,7 +11031,7 @@
                 },
                 "libnpm": {
                     "version": "3.0.1",
-                    "resolved": "https://registry.npmjs.org/libnpm/-/libnpm-3.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-d7jU5ZcMiTfBqTUJVZ3xid44fE5ERBm9vBnmhp2ECD2Ls+FNXWxHSkO7gtvrnbLO78gwPdNPz1HpsF3W4rjkBQ==",
                     "requires": {
                         "bin-links": "^1.1.2",
@@ -11078,7 +11058,7 @@
                 },
                 "libnpmaccess": {
                     "version": "3.0.2",
-                    "resolved": "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-3.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-01512AK7MqByrI2mfC7h5j8N9V4I7MHJuk9buo8Gv+5QgThpOgpjB7sQBDDkeZqRteFb1QM/6YNdHfG7cDvfAQ==",
                     "requires": {
                         "aproba": "^2.0.0",
@@ -11089,7 +11069,7 @@
                 },
                 "libnpmconfig": {
                     "version": "1.2.1",
-                    "resolved": "https://registry.npmjs.org/libnpmconfig/-/libnpmconfig-1.2.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==",
                     "requires": {
                         "figgy-pudding": "^3.5.1",
@@ -11099,7 +11079,7 @@
                     "dependencies": {
                         "find-up": {
                             "version": "3.0.0",
-                            "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                             "requires": {
                                 "locate-path": "^3.0.0"
@@ -11107,7 +11087,7 @@
                         },
                         "locate-path": {
                             "version": "3.0.0",
-                            "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                             "requires": {
                                 "p-locate": "^3.0.0",
@@ -11116,7 +11096,7 @@
                         },
                         "p-limit": {
                             "version": "2.2.0",
-                            "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
                             "requires": {
                                 "p-try": "^2.0.0"
@@ -11124,7 +11104,7 @@
                         },
                         "p-locate": {
                             "version": "3.0.0",
-                            "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                             "requires": {
                                 "p-limit": "^2.0.0"
@@ -11132,14 +11112,14 @@
                         },
                         "p-try": {
                             "version": "2.2.0",
-                            "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
                         }
                     }
                 },
                 "libnpmhook": {
                     "version": "5.0.3",
-                    "resolved": "https://registry.npmjs.org/libnpmhook/-/libnpmhook-5.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-UdNLMuefVZra/wbnBXECZPefHMGsVDTq5zaM/LgKNE9Keyl5YXQTnGAzEo+nFOpdRqTWI9LYi4ApqF9uVCCtuA==",
                     "requires": {
                         "aproba": "^2.0.0",
@@ -11150,7 +11130,7 @@
                 },
                 "libnpmorg": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/libnpmorg/-/libnpmorg-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-0sRUXLh+PLBgZmARvthhYXQAWn0fOsa6T5l3JSe2n9vKG/lCVK4nuG7pDsa7uMq+uTt2epdPK+a2g6btcY11Ww==",
                     "requires": {
                         "aproba": "^2.0.0",
@@ -11161,7 +11141,7 @@
                 },
                 "libnpmpublish": {
                     "version": "1.1.2",
-                    "resolved": "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-1.1.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-2yIwaXrhTTcF7bkJKIKmaCV9wZOALf/gsTDxVSu/Gu/6wiG3fA8ce8YKstiWKTxSFNC0R7isPUb6tXTVFZHt2g==",
                     "requires": {
                         "aproba": "^2.0.0",
@@ -11177,7 +11157,7 @@
                 },
                 "libnpmsearch": {
                     "version": "2.0.2",
-                    "resolved": "https://registry.npmjs.org/libnpmsearch/-/libnpmsearch-2.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-VTBbV55Q6fRzTdzziYCr64+f8AopQ1YZ+BdPOv16UegIEaE8C0Kch01wo4s3kRTFV64P121WZJwgmBwrq68zYg==",
                     "requires": {
                         "figgy-pudding": "^3.5.1",
@@ -11187,7 +11167,7 @@
                 },
                 "libnpmteam": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/libnpmteam/-/libnpmteam-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-p420vM28Us04NAcg1rzgGW63LMM6rwe+6rtZpfDxCcXxM0zUTLl7nPFEnRF3JfFBF5skF/yuZDUthTsHgde8QA==",
                     "requires": {
                         "aproba": "^2.0.0",
@@ -11198,7 +11178,7 @@
                 },
                 "libnpx": {
                     "version": "10.2.2",
-                    "resolved": "https://registry.npmjs.org/libnpx/-/libnpx-10.2.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-ujaYToga1SAX5r7FU5ShMFi88CWpY75meNZtr6RtEyv4l2ZK3+Wgvxq2IqlwWBiDZOqhumdeiocPS1aKrCMe3A==",
                     "requires": {
                         "dotenv": "^5.0.1",
@@ -11213,7 +11193,7 @@
                 },
                 "locate-path": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
                     "requires": {
                         "p-locate": "^2.0.0",
@@ -11222,7 +11202,7 @@
                 },
                 "lock-verify": {
                     "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/lock-verify/-/lock-verify-2.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-vcLpxnGvrqisKvLQ2C2v0/u7LVly17ak2YSgoK4PrdsYBXQIax19vhKiLfvKNFx7FRrpTnitrpzF/uuCMuorIg==",
                     "requires": {
                         "npm-package-arg": "^6.1.0",
@@ -11231,7 +11211,7 @@
                 },
                 "lockfile": {
                     "version": "1.0.4",
-                    "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==",
                     "requires": {
                         "signal-exit": "^3.0.2"
@@ -11239,12 +11219,12 @@
                 },
                 "lodash._baseindexof": {
                     "version": "3.1.0",
-                    "resolved": "https://registry.npmjs.org/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw="
                 },
                 "lodash._baseuniq": {
                     "version": "4.6.0",
-                    "resolved": "https://registry.npmjs.org/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg=",
                     "requires": {
                         "lodash._createset": "~4.0.0",
@@ -11253,17 +11233,17 @@
                 },
                 "lodash._bindcallback": {
                     "version": "3.0.1",
-                    "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4="
                 },
                 "lodash._cacheindexof": {
                     "version": "3.0.2",
-                    "resolved": "https://registry.npmjs.org/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI="
                 },
                 "lodash._createcache": {
                     "version": "3.1.2",
-                    "resolved": "https://registry.npmjs.org/lodash._createcache/-/lodash._createcache-3.1.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-VtagZAF2JeeevKa4AY4XRAvc8JM=",
                     "requires": {
                         "lodash._getnative": "^3.0.0"
@@ -11271,52 +11251,52 @@
                 },
                 "lodash._createset": {
                     "version": "4.0.3",
-                    "resolved": "https://registry.npmjs.org/lodash._createset/-/lodash._createset-4.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY="
                 },
                 "lodash._getnative": {
                     "version": "3.9.1",
-                    "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U="
                 },
                 "lodash._root": {
                     "version": "3.0.1",
-                    "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI="
                 },
                 "lodash.clonedeep": {
                     "version": "4.5.0",
-                    "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
                 },
                 "lodash.restparam": {
                     "version": "3.6.1",
-                    "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU="
                 },
                 "lodash.union": {
                     "version": "4.6.0",
-                    "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg="
                 },
                 "lodash.uniq": {
                     "version": "4.5.0",
-                    "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M="
                 },
                 "lodash.without": {
                     "version": "4.4.0",
-                    "resolved": "https://registry.npmjs.org/lodash.without/-/lodash.without-4.4.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-PNRXSgC2e643OpS3SHcmQFB7eqw="
                 },
                 "lowercase-keys": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
                 },
                 "lru-cache": {
                     "version": "5.1.1",
-                    "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
                     "requires": {
                         "yallist": "^3.0.2"
@@ -11324,7 +11304,7 @@
                 },
                 "make-dir": {
                     "version": "1.3.0",
-                    "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
                     "requires": {
                         "pify": "^3.0.0"
@@ -11332,7 +11312,7 @@
                 },
                 "make-fetch-happen": {
                     "version": "5.0.2",
-                    "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag==",
                     "requires": {
                         "agentkeepalive": "^3.4.1",
@@ -11350,7 +11330,7 @@
                 },
                 "map-age-cleaner": {
                     "version": "0.1.3",
-                    "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
                     "requires": {
                         "p-defer": "^1.0.0"
@@ -11358,12 +11338,12 @@
                 },
                 "meant": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/meant/-/meant-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-UakVLFjKkbbUwNWJ2frVLnnAtbb7D7DsloxRd3s/gDpI8rdv8W5Hp3NaDb+POBI1fQdeussER6NB8vpcRURvlg=="
                 },
                 "mem": {
                     "version": "4.3.0",
-                    "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
                     "requires": {
                         "map-age-cleaner": "^0.1.1",
@@ -11373,19 +11353,19 @@
                     "dependencies": {
                         "mimic-fn": {
                             "version": "2.1.0",
-                            "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
                         }
                     }
                 },
                 "mime-db": {
                     "version": "1.35.0",
-                    "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg=="
                 },
                 "mime-types": {
                     "version": "2.1.19",
-                    "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz",
+                    "resolved": false,
                     "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==",
                     "requires": {
                         "mime-db": "~1.35.0"
@@ -11393,7 +11373,7 @@
                 },
                 "minimatch": {
                     "version": "3.0.4",
-                    "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
                     "requires": {
                         "brace-expansion": "^1.1.7"
@@ -11401,7 +11381,7 @@
                 },
                 "minizlib": {
                     "version": "1.3.3",
-                    "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
                     "requires": {
                         "minipass": "^2.9.0"
@@ -11409,7 +11389,7 @@
                     "dependencies": {
                         "minipass": {
                             "version": "2.9.0",
-                            "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
                             "requires": {
                                 "safe-buffer": "^5.1.2",
@@ -11420,7 +11400,7 @@
                 },
                 "mississippi": {
                     "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
                     "requires": {
                         "concat-stream": "^1.5.0",
@@ -11452,7 +11432,7 @@
                 },
                 "move-concurrently": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
                     "requires": {
                         "aproba": "^1.1.1",
@@ -11465,29 +11445,29 @@
                     "dependencies": {
                         "aproba": {
                             "version": "1.2.0",
-                            "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
                         }
                     }
                 },
                 "ms": {
                     "version": "2.1.1",
-                    "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
                 },
                 "mute-stream": {
                     "version": "0.0.7",
-                    "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+                    "resolved": false,
                     "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
                 },
                 "nice-try": {
                     "version": "1.0.5",
-                    "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+                    "resolved": false,
                     "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
                 },
                 "node-fetch-npm": {
                     "version": "2.0.2",
-                    "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw==",
                     "requires": {
                         "encoding": "^0.1.11",
@@ -11515,7 +11495,7 @@
                 },
                 "nopt": {
                     "version": "4.0.1",
-                    "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
                     "requires": {
                         "abbrev": "1",
@@ -11524,7 +11504,7 @@
                 },
                 "normalize-package-data": {
                     "version": "2.5.0",
-                    "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
                     "requires": {
                         "hosted-git-info": "^2.1.4",
@@ -11535,7 +11515,7 @@
                     "dependencies": {
                         "resolve": {
                             "version": "1.10.0",
-                            "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==",
                             "requires": {
                                 "path-parse": "^1.0.6"
@@ -11545,7 +11525,7 @@
                 },
                 "npm-audit-report": {
                     "version": "1.3.2",
-                    "resolved": "https://registry.npmjs.org/npm-audit-report/-/npm-audit-report-1.3.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-abeqS5ONyXNaZJPGAf6TOUMNdSe1Y6cpc9MLBRn+CuUoYbfdca6AxOyXVlfIv9OgKX+cacblbG5w7A6ccwoTPw==",
                     "requires": {
                         "cli-table3": "^0.5.0",
@@ -11554,7 +11534,7 @@
                 },
                 "npm-bundled": {
                     "version": "1.1.1",
-                    "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==",
                     "requires": {
                         "npm-normalize-package-bin": "^1.0.1"
@@ -11562,12 +11542,12 @@
                 },
                 "npm-cache-filename": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE="
                 },
                 "npm-install-checks": {
                     "version": "3.0.2",
-                    "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-3.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-E4kzkyZDIWoin6uT5howP8VDvkM+E8IQDcHAycaAxMbwkqhIg5eEYALnXOl3Hq9MrkdQB/2/g1xwBINXdKSRkg==",
                     "requires": {
                         "semver": "^2.3.0 || 3.x || 4 || 5"
@@ -11575,7 +11555,7 @@
                 },
                 "npm-lifecycle": {
                     "version": "3.1.4",
-                    "resolved": "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-3.1.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-tgs1PaucZwkxECGKhC/stbEgFyc3TGh2TJcg2CDr6jbvQRdteHNhmMeljRzpe4wgFAXQADoy1cSqqi7mtiAa5A==",
                     "requires": {
                         "byline": "^5.0.0",
@@ -11590,17 +11570,17 @@
                 },
                 "npm-logical-tree": {
                     "version": "1.2.1",
-                    "resolved": "https://registry.npmjs.org/npm-logical-tree/-/npm-logical-tree-1.2.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-AJI/qxDB2PWI4LG1CYN579AY1vCiNyWfkiquCsJWqntRu/WwimVrC8yXeILBFHDwxfOejxewlmnvW9XXjMlYIg=="
                 },
                 "npm-normalize-package-bin": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA=="
                 },
                 "npm-package-arg": {
                     "version": "6.1.1",
-                    "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==",
                     "requires": {
                         "hosted-git-info": "^2.7.1",
@@ -11621,7 +11601,7 @@
                 },
                 "npm-pick-manifest": {
                     "version": "3.0.2",
-                    "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==",
                     "requires": {
                         "figgy-pudding": "^3.5.1",
@@ -11655,14 +11635,14 @@
                     "dependencies": {
                         "safe-buffer": {
                             "version": "5.2.0",
-                            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
                         }
                     }
                 },
                 "npm-run-path": {
                     "version": "2.0.2",
-                    "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
                     "requires": {
                         "path-key": "^2.0.0"
@@ -11670,12 +11650,12 @@
                 },
                 "npm-user-validate": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/npm-user-validate/-/npm-user-validate-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-jOyg9c6gTU6TUZ73LQVXp1Ei6VE="
                 },
                 "npmlog": {
                     "version": "4.1.2",
-                    "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
                     "requires": {
                         "are-we-there-yet": "~1.1.2",
@@ -11686,27 +11666,27 @@
                 },
                 "number-is-nan": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
                 },
                 "oauth-sign": {
                     "version": "0.9.0",
-                    "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
                 },
                 "object-assign": {
                     "version": "4.1.1",
-                    "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
                 },
                 "object-keys": {
                     "version": "1.0.12",
-                    "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
+                    "resolved": false,
                     "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag=="
                 },
                 "object.getownpropertydescriptors": {
                     "version": "2.0.3",
-                    "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
                     "requires": {
                         "define-properties": "^1.1.2",
@@ -11715,7 +11695,7 @@
                 },
                 "once": {
                     "version": "1.4.0",
-                    "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
                     "requires": {
                         "wrappy": "1"
@@ -11723,17 +11703,17 @@
                 },
                 "opener": {
                     "version": "1.5.1",
-                    "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA=="
                 },
                 "os-homedir": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
                 },
                 "os-locale": {
                     "version": "3.1.0",
-                    "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
                     "requires": {
                         "execa": "^1.0.0",
@@ -11743,7 +11723,7 @@
                     "dependencies": {
                         "cross-spawn": {
                             "version": "6.0.5",
-                            "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+                            "resolved": false,
                             "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
                             "requires": {
                                 "nice-try": "^1.0.4",
@@ -11755,7 +11735,7 @@
                         },
                         "execa": {
                             "version": "1.0.0",
-                            "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
                             "requires": {
                                 "cross-spawn": "^6.0.0",
@@ -11771,12 +11751,12 @@
                 },
                 "os-tmpdir": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
                 },
                 "osenv": {
                     "version": "0.1.5",
-                    "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+                    "resolved": false,
                     "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
                     "requires": {
                         "os-homedir": "^1.0.0",
@@ -11785,22 +11765,22 @@
                 },
                 "p-defer": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww="
                 },
                 "p-finally": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
                 },
                 "p-is-promise": {
                     "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg=="
                 },
                 "p-limit": {
                     "version": "1.2.0",
-                    "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==",
                     "requires": {
                         "p-try": "^1.0.0"
@@ -11808,7 +11788,7 @@
                 },
                 "p-locate": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
                     "requires": {
                         "p-limit": "^1.1.0"
@@ -11816,12 +11796,12 @@
                 },
                 "p-try": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M="
                 },
                 "package-json": {
                     "version": "4.0.1",
-                    "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
                     "requires": {
                         "got": "^6.7.1",
@@ -11832,7 +11812,7 @@
                 },
                 "pacote": {
                     "version": "9.5.12",
-                    "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.12.tgz",
+                    "resolved": false,
                     "integrity": "sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ==",
                     "requires": {
                         "bluebird": "^3.5.3",
@@ -11869,7 +11849,7 @@
                     "dependencies": {
                         "minipass": {
                             "version": "2.9.0",
-                            "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
                             "requires": {
                                 "safe-buffer": "^5.1.2",
@@ -11880,7 +11860,7 @@
                 },
                 "parallel-transform": {
                     "version": "1.1.0",
-                    "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
                     "requires": {
                         "cyclist": "~0.2.2",
@@ -11890,7 +11870,7 @@
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
-                            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+                            "resolved": false,
                             "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
                             "requires": {
                                 "core-util-is": "~1.0.0",
@@ -11904,7 +11884,7 @@
                         },
                         "string_decoder": {
                             "version": "1.1.1",
-                            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+                            "resolved": false,
                             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
                             "requires": {
                                 "safe-buffer": "~5.1.0"
@@ -11914,57 +11894,57 @@
                 },
                 "path-exists": {
                     "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
                 },
                 "path-is-absolute": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
                 },
                 "path-is-inside": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM="
                 },
                 "path-key": {
                     "version": "2.0.1",
-                    "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
                 },
                 "path-parse": {
                     "version": "1.0.6",
-                    "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+                    "resolved": false,
                     "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
                 },
                 "performance-now": {
                     "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
                 },
                 "pify": {
                     "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
                 },
                 "prepend-http": {
                     "version": "1.0.4",
-                    "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+                    "resolved": false,
                     "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
                 },
                 "process-nextick-args": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
                 },
                 "promise-inflight": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM="
                 },
                 "promise-retry": {
                     "version": "1.1.1",
-                    "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=",
                     "requires": {
                         "err-code": "^1.0.0",
@@ -11973,14 +11953,14 @@
                     "dependencies": {
                         "retry": {
                             "version": "0.10.1",
-                            "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz",
+                            "resolved": false,
                             "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q="
                         }
                     }
                 },
                 "promzard": {
                     "version": "0.3.0",
-                    "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-JqXW7ox97kyxIggwWs+5O6OCqe4=",
                     "requires": {
                         "read": "1"
@@ -11988,12 +11968,12 @@
                 },
                 "proto-list": {
                     "version": "1.2.4",
-                    "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+                    "resolved": false,
                     "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk="
                 },
                 "protoduck": {
                     "version": "5.0.1",
-                    "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==",
                     "requires": {
                         "genfun": "^5.0.0"
@@ -12001,22 +11981,22 @@
                 },
                 "prr": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY="
                 },
                 "pseudomap": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
                 },
                 "psl": {
                     "version": "1.1.29",
-                    "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz",
+                    "resolved": false,
                     "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ=="
                 },
                 "pump": {
                     "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
                     "requires": {
                         "end-of-stream": "^1.1.0",
@@ -12025,7 +12005,7 @@
                 },
                 "pumpify": {
                     "version": "1.5.1",
-                    "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
                     "requires": {
                         "duplexify": "^3.6.0",
@@ -12035,7 +12015,7 @@
                     "dependencies": {
                         "pump": {
                             "version": "2.0.1",
-                            "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+                            "resolved": false,
                             "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
                             "requires": {
                                 "end-of-stream": "^1.1.0",
@@ -12046,22 +12026,22 @@
                 },
                 "punycode": {
                     "version": "1.4.1",
-                    "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
                 },
                 "qrcode-terminal": {
                     "version": "0.12.0",
-                    "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ=="
                 },
                 "qs": {
                     "version": "6.5.2",
-                    "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
                 },
                 "query-string": {
                     "version": "6.8.2",
-                    "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.8.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-J3Qi8XZJXh93t2FiKyd/7Ec6GNifsjKXUsVFkSBj/kjLsDylWhnCz4NT1bkPcKotttPW+QbKGqqPH8OoI2pdqw==",
                     "requires": {
                         "decode-uri-component": "^0.2.0",
@@ -12071,7 +12051,7 @@
                 },
                 "qw": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/qw/-/qw-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-77/cdA+a0FQwRCassYNBLMi5ltQ="
                 },
                 "rc": {
@@ -12094,7 +12074,7 @@
                 },
                 "read": {
                     "version": "1.0.7",
-                    "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+                    "resolved": false,
                     "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
                     "requires": {
                         "mute-stream": "~0.0.4"
@@ -12102,7 +12082,7 @@
                 },
                 "read-cmd-shim": {
                     "version": "1.0.5",
-                    "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz",
+                    "resolved": false,
                     "integrity": "sha512-v5yCqQ/7okKoZZkBQUAfTsQ3sVJtXdNfbPnI5cceppoxEVLYA3k+VtV2omkeo8MS94JCy4fSiUwlRBAwCVRPUA==",
                     "requires": {
                         "graceful-fs": "^4.1.2"
@@ -12110,7 +12090,7 @@
                 },
                 "read-installed": {
                     "version": "4.0.3",
-                    "resolved": "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc=",
                     "requires": {
                         "debuglog": "^1.0.1",
@@ -12124,7 +12104,7 @@
                 },
                 "read-package-json": {
                     "version": "2.1.1",
-                    "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-dAiqGtVc/q5doFz6096CcnXhpYk0ZN8dEKVkGLU0CsASt8SrgF6SF7OTKAYubfvFhWaqofl+Y8HK19GR8jwW+A==",
                     "requires": {
                         "glob": "^7.1.1",
@@ -12136,7 +12116,7 @@
                 },
                 "read-package-tree": {
                     "version": "5.3.1",
-                    "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==",
                     "requires": {
                         "read-package-json": "^2.0.0",
@@ -12156,7 +12136,7 @@
                 },
                 "readdir-scoped-modules": {
                     "version": "1.1.0",
-                    "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==",
                     "requires": {
                         "debuglog": "^1.0.1",
@@ -12176,7 +12156,7 @@
                 },
                 "registry-url": {
                     "version": "3.1.0",
-                    "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
                     "requires": {
                         "rc": "^1.0.1"
@@ -12184,7 +12164,7 @@
                 },
                 "request": {
                     "version": "2.88.0",
-                    "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
                     "requires": {
                         "aws-sign2": "~0.7.0",
@@ -12211,22 +12191,22 @@
                 },
                 "require-directory": {
                     "version": "2.1.1",
-                    "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
                 },
                 "require-main-filename": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
                 },
                 "resolve-from": {
                     "version": "4.0.0",
-                    "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
                 },
                 "retry": {
                     "version": "0.12.0",
-                    "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs="
                 },
                 "rimraf": {
@@ -12239,7 +12219,7 @@
                 },
                 "run-queue": {
                     "version": "1.0.3",
-                    "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
                     "requires": {
                         "aproba": "^1.1.1"
@@ -12247,29 +12227,29 @@
                     "dependencies": {
                         "aproba": {
                             "version": "1.2.0",
-                            "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
                         }
                     }
                 },
                 "safe-buffer": {
                     "version": "5.1.2",
-                    "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
                 },
                 "safer-buffer": {
                     "version": "2.1.2",
-                    "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
                 },
                 "semver": {
                     "version": "5.7.1",
-                    "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
                 },
                 "semver-diff": {
                     "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
                     "requires": {
                         "semver": "^5.0.3"
@@ -12277,12 +12257,12 @@
                 },
                 "set-blocking": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
                 },
                 "sha": {
                     "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/sha/-/sha-3.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-DOYnM37cNsLNSGIG/zZWch5CKIRNoLdYUQTQlcgkRkoYIUwDYjqDyye16YcDZg/OPdcbUgTKMjc4SY6TB7ZAPw==",
                     "requires": {
                         "graceful-fs": "^4.1.2"
@@ -12290,7 +12270,7 @@
                 },
                 "shebang-command": {
                     "version": "1.2.0",
-                    "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
                     "requires": {
                         "shebang-regex": "^1.0.0"
@@ -12298,27 +12278,27 @@
                 },
                 "shebang-regex": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
                 },
                 "signal-exit": {
                     "version": "3.0.2",
-                    "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
                 },
                 "slide": {
                     "version": "1.1.6",
-                    "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
+                    "resolved": false,
                     "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc="
                 },
                 "smart-buffer": {
                     "version": "4.1.0",
-                    "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw=="
                 },
                 "socks": {
                     "version": "2.3.3",
-                    "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==",
                     "requires": {
                         "ip": "1.1.5",
@@ -12327,7 +12307,7 @@
                 },
                 "socks-proxy-agent": {
                     "version": "4.0.2",
-                    "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==",
                     "requires": {
                         "agent-base": "~4.2.1",
@@ -12336,7 +12316,7 @@
                     "dependencies": {
                         "agent-base": {
                             "version": "4.2.1",
-                            "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
+                            "resolved": false,
                             "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
                             "requires": {
                                 "es6-promisify": "^5.0.0"
@@ -12346,12 +12326,12 @@
                 },
                 "sorted-object": {
                     "version": "2.0.1",
-                    "resolved": "https://registry.npmjs.org/sorted-object/-/sorted-object-2.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw="
                 },
                 "sorted-union-stream": {
                     "version": "2.1.3",
-                    "resolved": "https://registry.npmjs.org/sorted-union-stream/-/sorted-union-stream-2.1.3.tgz",
+                    "resolved": false,
                     "integrity": "sha1-x3lMfgd4gAUv9xqNSi27Sppjisc=",
                     "requires": {
                         "from2": "^1.3.0",
@@ -12360,7 +12340,7 @@
                     "dependencies": {
                         "from2": {
                             "version": "1.3.0",
-                            "resolved": "https://registry.npmjs.org/from2/-/from2-1.3.0.tgz",
+                            "resolved": false,
                             "integrity": "sha1-iEE7qqX5pZfP3pIh2GmGzTwGHf0=",
                             "requires": {
                                 "inherits": "~2.0.1",
@@ -12369,12 +12349,12 @@
                         },
                         "isarray": {
                             "version": "0.0.1",
-                            "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+                            "resolved": false,
                             "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
                         },
                         "readable-stream": {
                             "version": "1.1.14",
-                            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+                            "resolved": false,
                             "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
                             "requires": {
                                 "core-util-is": "~1.0.0",
@@ -12385,14 +12365,14 @@
                         },
                         "string_decoder": {
                             "version": "0.10.31",
-                            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+                            "resolved": false,
                             "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
                         }
                     }
                 },
                 "spdx-correct": {
                     "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==",
                     "requires": {
                         "spdx-expression-parse": "^3.0.0",
@@ -12401,12 +12381,12 @@
                 },
                 "spdx-exceptions": {
                     "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg=="
                 },
                 "spdx-expression-parse": {
                     "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
                     "requires": {
                         "spdx-exceptions": "^2.1.0",
@@ -12415,17 +12395,17 @@
                 },
                 "spdx-license-ids": {
                     "version": "3.0.3",
-                    "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g=="
                 },
                 "split-on-first": {
                     "version": "1.1.0",
-                    "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
                 },
                 "sshpk": {
                     "version": "1.14.2",
-                    "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=",
                     "requires": {
                         "asn1": "~0.2.3",
@@ -12441,7 +12421,7 @@
                 },
                 "ssri": {
                     "version": "6.0.1",
-                    "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
                     "requires": {
                         "figgy-pudding": "^3.5.1"
@@ -12449,7 +12429,7 @@
                 },
                 "stream-each": {
                     "version": "1.2.2",
-                    "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==",
                     "requires": {
                         "end-of-stream": "^1.1.0",
@@ -12458,7 +12438,7 @@
                 },
                 "stream-iterate": {
                     "version": "1.2.0",
-                    "resolved": "https://registry.npmjs.org/stream-iterate/-/stream-iterate-1.2.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-K9fHcpbBcCpGSIuK1B95hl7s1OE=",
                     "requires": {
                         "readable-stream": "^2.1.5",
@@ -12467,7 +12447,7 @@
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
-                            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+                            "resolved": false,
                             "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
                             "requires": {
                                 "core-util-is": "~1.0.0",
@@ -12481,7 +12461,7 @@
                         },
                         "string_decoder": {
                             "version": "1.1.1",
-                            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+                            "resolved": false,
                             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
                             "requires": {
                                 "safe-buffer": "~5.1.0"
@@ -12491,17 +12471,17 @@
                 },
                 "stream-shift": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI="
                 },
                 "strict-uri-encode": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
                 },
                 "string-width": {
                     "version": "2.1.1",
-                    "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
                     "requires": {
                         "is-fullwidth-code-point": "^2.0.0",
@@ -12510,17 +12490,17 @@
                     "dependencies": {
                         "ansi-regex": {
                             "version": "3.0.0",
-                            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+                            "resolved": false,
                             "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
                         },
                         "is-fullwidth-code-point": {
                             "version": "2.0.0",
-                            "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+                            "resolved": false,
                             "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
                         },
                         "strip-ansi": {
                             "version": "4.0.0",
-                            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+                            "resolved": false,
                             "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                             "requires": {
                                 "ansi-regex": "^3.0.0"
@@ -12545,12 +12525,12 @@
                 },
                 "stringify-package": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg=="
                 },
                 "strip-ansi": {
                     "version": "3.0.1",
-                    "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
                     "requires": {
                         "ansi-regex": "^2.0.0"
@@ -12558,17 +12538,17 @@
                 },
                 "strip-eof": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
                 },
                 "strip-json-comments": {
                     "version": "2.0.1",
-                    "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
                 },
                 "supports-color": {
                     "version": "5.4.0",
-                    "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
                     "requires": {
                         "has-flag": "^3.0.0"
@@ -12576,7 +12556,7 @@
                 },
                 "tar": {
                     "version": "4.4.13",
-                    "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
+                    "resolved": false,
                     "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
                     "requires": {
                         "chownr": "^1.1.1",
@@ -12590,7 +12570,7 @@
                     "dependencies": {
                         "minipass": {
                             "version": "2.9.0",
-                            "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
                             "requires": {
                                 "safe-buffer": "^5.1.2",
@@ -12601,7 +12581,7 @@
                 },
                 "term-size": {
                     "version": "1.2.0",
-                    "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
                     "requires": {
                         "execa": "^0.7.0"
@@ -12609,17 +12589,17 @@
                 },
                 "text-table": {
                     "version": "0.2.0",
-                    "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
                 },
                 "through": {
                     "version": "2.3.8",
-                    "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+                    "resolved": false,
                     "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
                 },
                 "through2": {
                     "version": "2.0.3",
-                    "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
                     "requires": {
                         "readable-stream": "^2.1.5",
@@ -12628,7 +12608,7 @@
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
-                            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+                            "resolved": false,
                             "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
                             "requires": {
                                 "core-util-is": "~1.0.0",
@@ -12642,7 +12622,7 @@
                         },
                         "string_decoder": {
                             "version": "1.1.1",
-                            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+                            "resolved": false,
                             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
                             "requires": {
                                 "safe-buffer": "~5.1.0"
@@ -12652,17 +12632,17 @@
                 },
                 "timed-out": {
                     "version": "4.0.1",
-                    "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
                 },
                 "tiny-relative-date": {
                     "version": "1.3.0",
-                    "resolved": "https://registry.npmjs.org/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A=="
                 },
                 "tough-cookie": {
                     "version": "2.4.3",
-                    "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
                     "requires": {
                         "psl": "^1.1.24",
@@ -12671,7 +12651,7 @@
                 },
                 "tunnel-agent": {
                     "version": "0.6.0",
-                    "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
                     "requires": {
                         "safe-buffer": "^5.0.1"
@@ -12679,28 +12659,28 @@
                 },
                 "tweetnacl": {
                     "version": "0.14.5",
-                    "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+                    "resolved": false,
                     "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
                     "optional": true
                 },
                 "typedarray": {
                     "version": "0.0.6",
-                    "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+                    "resolved": false,
                     "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
                 },
                 "uid-number": {
                     "version": "0.0.6",
-                    "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz",
+                    "resolved": false,
                     "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE="
                 },
                 "umask": {
                     "version": "1.1.0",
-                    "resolved": "https://registry.npmjs.org/umask/-/umask-1.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0="
                 },
                 "unique-filename": {
                     "version": "1.1.1",
-                    "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
                     "requires": {
                         "unique-slug": "^2.0.0"
@@ -12708,7 +12688,7 @@
                 },
                 "unique-slug": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=",
                     "requires": {
                         "imurmurhash": "^0.1.4"
@@ -12716,7 +12696,7 @@
                 },
                 "unique-string": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
                     "requires": {
                         "crypto-random-string": "^1.0.0"
@@ -12724,17 +12704,17 @@
                 },
                 "unpipe": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
                 },
                 "unzip-response": {
                     "version": "2.0.1",
-                    "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c="
                 },
                 "update-notifier": {
                     "version": "2.5.0",
-                    "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==",
                     "requires": {
                         "boxen": "^1.2.1",
@@ -12751,7 +12731,7 @@
                 },
                 "url-parse-lax": {
                     "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
                     "requires": {
                         "prepend-http": "^1.0.1"
@@ -12759,17 +12739,17 @@
                 },
                 "util-deprecate": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
                 },
                 "util-extend": {
                     "version": "1.0.3",
-                    "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8="
                 },
                 "util-promisify": {
                     "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/util-promisify/-/util-promisify-2.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=",
                     "requires": {
                         "object.getownpropertydescriptors": "^2.0.3"
@@ -12777,12 +12757,12 @@
                 },
                 "uuid": {
                     "version": "3.3.3",
-                    "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ=="
                 },
                 "validate-npm-package-license": {
                     "version": "3.0.4",
-                    "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
                     "requires": {
                         "spdx-correct": "^3.0.0",
@@ -12791,7 +12771,7 @@
                 },
                 "validate-npm-package-name": {
                     "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=",
                     "requires": {
                         "builtins": "^1.0.3"
@@ -12799,7 +12779,7 @@
                 },
                 "verror": {
                     "version": "1.10.0",
-                    "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
                     "requires": {
                         "assert-plus": "^1.0.0",
@@ -12809,7 +12789,7 @@
                 },
                 "wcwidth": {
                     "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
                     "requires": {
                         "defaults": "^1.0.3"
@@ -12817,7 +12797,7 @@
                 },
                 "which": {
                     "version": "1.3.1",
-                    "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
                     "requires": {
                         "isexe": "^2.0.0"
@@ -12825,12 +12805,12 @@
                 },
                 "which-module": {
                     "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
                 },
                 "wide-align": {
                     "version": "1.1.2",
-                    "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
+                    "resolved": false,
                     "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
                     "requires": {
                         "string-width": "^1.0.2"
@@ -12838,7 +12818,7 @@
                     "dependencies": {
                         "string-width": {
                             "version": "1.0.2",
-                            "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+                            "resolved": false,
                             "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
                             "requires": {
                                 "code-point-at": "^1.0.0",
@@ -12858,7 +12838,7 @@
                 },
                 "worker-farm": {
                     "version": "1.7.0",
-                    "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
                     "requires": {
                         "errno": "~0.1.7"
@@ -12866,7 +12846,7 @@
                 },
                 "wrap-ansi": {
                     "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
                     "requires": {
                         "string-width": "^1.0.1",
@@ -12875,7 +12855,7 @@
                     "dependencies": {
                         "string-width": {
                             "version": "1.0.2",
-                            "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+                            "resolved": false,
                             "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
                             "requires": {
                                 "code-point-at": "^1.0.0",
@@ -12887,12 +12867,12 @@
                 },
                 "wrappy": {
                     "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
                 },
                 "write-file-atomic": {
                     "version": "2.4.3",
-                    "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
                     "requires": {
                         "graceful-fs": "^4.1.11",
@@ -12902,27 +12882,27 @@
                 },
                 "xdg-basedir": {
                     "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ="
                 },
                 "xtend": {
                     "version": "4.0.1",
-                    "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
                 },
                 "y18n": {
                     "version": "4.0.0",
-                    "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
                 },
                 "yallist": {
                     "version": "3.0.3",
-                    "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A=="
                 },
                 "yargs": {
                     "version": "11.1.1",
-                    "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-PRU7gJrJaXv3q3yQZ/+/X6KBswZiaQ+zOmdprZcouPYtQgvNU35i+68M4b1ZHLZtYFT5QObFLV+ZkmJYcwKdiw==",
                     "requires": {
                         "cliui": "^4.0.0",
@@ -12941,14 +12921,14 @@
                     "dependencies": {
                         "y18n": {
                             "version": "3.2.1",
-                            "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+                            "resolved": false,
                             "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
                         }
                     }
                 },
                 "yargs-parser": {
                     "version": "9.0.2",
-                    "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz",
+                    "resolved": false,
                     "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=",
                     "requires": {
                         "camelcase": "^4.1.0"
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 421bf90c1..6949670d6 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -26,6 +26,7 @@ import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewField
 import { CollectionSubView } from "./CollectionSubView";
 import { CollectionViewType } from "./CollectionView";
 import { SnappingManager } from "../../util/SnappingManager";
+import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
 const _global = (window /* browser */ || global /* node */) as any;
 
 type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>;
@@ -191,8 +192,8 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
     }
 
     getDisplayDoc(doc: Doc, dataDoc: Doc | undefined, dxf: () => Transform, width: () => number) {
-        const layoutDoc = Doc.Layout(doc, this.props.ChildLayoutTemplate?.());
         const height = () => this.getDocHeight(doc);
+        const opacity = () => this.Document.currentTimecode === undefined ? this.props.childOpacity?.() : CollectionFreeFormDocumentView.getValues(doc, this.Document.currentTimecode || 0)?.opacity;
         return <ContentFittingDocumentView
             Document={doc}
             DataDoc={dataDoc || (doc[DataSym] !== doc && doc[DataSym])}
@@ -213,7 +214,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
             onClick={this.onChildClickHandler}
             onDoubleClick={this.onChildDoubleClickHandler}
             ScreenToLocalTransform={dxf}
-            opacity={this.props.childOpacity}
+            opacity={opacity}
             focus={this.focusDocument}
             ContainingCollectionDoc={this.props.CollectionView?.props.Document}
             ContainingCollectionView={this.props.CollectionView}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 1cdcd9b27..ee4755355 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -493,7 +493,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
         return (<div className={"collectionView"}
             style={{
                 pointerEvents: this.props.Document.isBackground ? "none" : undefined,
-                boxShadow: this.props.Document.isBackground || this.collectionViewType === CollectionViewType.Linear ? undefined :
+                boxShadow: Doc.UserDoc().renderStyle === "comic" || this.props.Document.isBackground || this.collectionViewType === CollectionViewType.Linear ? undefined :
                     `${Cast(Doc.UserDoc().activeWorkspace, Doc, null)?.darkScheme ? "rgb(30, 32, 31)" : "#9c9396"} ${StrCast(this.props.Document.boxShadow, "0.2vw 0.2vw 0.8vw")}`
             }}
             onContextMenu={this.onContextMenu}>
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index b9d33da90..d0540e00f 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -92,7 +92,7 @@ export interface DocumentViewProps {
     pinToPres: (document: Doc) => void;
     backgroundHalo?: () => boolean;
     backgroundColor?: (doc: Doc) => string | undefined;
-    opacity?: () => number;
+    opacity?: () => number | undefined;
     ChromeHeight?: () => number;
     dontRegisterView?: boolean;
     layoutKey?: string;
-- 
cgit v1.2.3-70-g09d2


From dd0c1f98d3f3056360ab7bacab6a5c98577ebafc Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Wed, 20 May 2020 02:11:22 -0700
Subject: cors proxy error no longer crashes server

---
 src/client/views/nodes/DocumentView.tsx |  8 ++++---
 src/server/server_Initialization.ts     | 39 ++++++++++++++++++---------------
 2 files changed, 26 insertions(+), 21 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index d0540e00f..34aabfe5e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -765,10 +765,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             moreItems.push({ description: "Write Back Link to Album", event: () => GooglePhotos.Transactions.AddTextEnrichment(this.props.Document), icon: "caret-square-right" });
         }
         moreItems.push({
-            description: "Download document", icon: "download", event: async () =>
-                console.log(JSON.parse(await rp.get(Utils.CorsProxy("http://localhost:8983/solr/dash/select"), {
+            description: "Download document", icon: "download", event: async () => {
+                const response = await rp.get(Utils.CorsProxy("http://localhost:8983/solr/dash/select"), {
                     qs: { q: 'world', fq: 'NOT baseProto_b:true AND NOT deleted:true', start: '0', rows: '100', hl: true, 'hl.fl': '*' }
-                })))
+                });
+                console.log(response ? JSON.parse(response) : undefined);
+            }
             // const a = document.createElement("a");
             // const url = Utils.prepend(`/downloadId/${this.props.Document[Id]}`);
             // a.href = url;
diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts
index 68954fa44..d370385b2 100644
--- a/src/server/server_Initialization.ts
+++ b/src/server/server_Initialization.ts
@@ -135,7 +135,7 @@ function registerAuthenticationRoutes(server: express.Express) {
 
 function registerCorsProxy(server: express.Express) {
     const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
-    server.use("/corsProxy", (req, res) => {
+    server.use("/corsProxy", async (req, res) => {
 
         const requrl = decodeURIComponent(req.url.substring(1));
         const referer = req.headers.referer ? decodeURIComponent(req.headers.referer) : "";
@@ -144,25 +144,28 @@ function registerCorsProxy(server: express.Express) {
         // then we redirect again to the cors referer and just add the relative path.
         if (!requrl.startsWith("http") && req.originalUrl.startsWith("/corsProxy") && referer?.includes("corsProxy")) {
             res.redirect(referer + (referer.endsWith("/") ? "" : "/") + requrl);
-        }
-        else {
+        } else {
             try {
-                req.pipe(request(requrl)).on("response", res => {
-                    const headers = Object.keys(res.headers);
-                    headers.forEach(headerName => {
-                        const header = res.headers[headerName];
-                        if (Array.isArray(header)) {
-                            res.headers[headerName] = header.filter(h => !headerCharRegex.test(h));
-                        } else if (header) {
-                            if (headerCharRegex.test(header as any)) {
-                                delete res.headers[headerName];
-                            }
-                        }
-                    });
-                }).pipe(res);
-            } catch (e) {
-                console.log("problem with Cors URL: " + requrl);
+                await new Promise<void>((resolve, reject) => {
+                    request(requrl).on("response", resolve).on("error", reject);
+                });
+            } catch {
+                console.log(`Malformed CORS url: ${requrl}`);
+                return res.send();
             }
+            req.pipe(request(requrl)).on("response", res => {
+                const headers = Object.keys(res.headers);
+                headers.forEach(headerName => {
+                    const header = res.headers[headerName];
+                    if (Array.isArray(header)) {
+                        res.headers[headerName] = header.filter(h => !headerCharRegex.test(h));
+                    } else if (header) {
+                        if (headerCharRegex.test(header as any)) {
+                            delete res.headers[headerName];
+                        }
+                    }
+                });
+            }).on("error", () => console.log(`Malformed CORS url: ${requrl}`)).pipe(res);
         }
     });
 }
-- 
cgit v1.2.3-70-g09d2


From 8de8756e5fa8b7031092c870c84f5214e2a244c1 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 20 May 2020 12:16:56 -0400
Subject: fixed up interaction with web pages to allow horizontal scrolling.

---
 src/client/documents/Documents.ts                  |  4 +--
 src/client/views/collections/CollectionMapView.tsx |  4 +--
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 11 +++++--
 src/client/views/nodes/DocumentView.tsx            |  7 -----
 src/client/views/nodes/WebBox.tsx                  | 35 ++++++++++++----------
 src/client/views/pdf/PDFViewer.tsx                 |  1 -
 src/fields/documentSchemas.ts                      |  6 ++--
 7 files changed, 36 insertions(+), 32 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 18a0b43ff..b859086d5 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -112,7 +112,7 @@ export interface DocumentOptions {
     caption?: RichTextField;
     ignoreClick?: boolean;
     lockedPosition?: boolean; // lock the x,y coordinates of the document so that it can't be dragged
-    lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed
+    _lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed
     isAnnotating?: boolean; // whether we web document is annotation mode where links can't be clicked to allow annotations to be created
     opacity?: number;
     defaultBackgroundColor?: string;
@@ -635,7 +635,7 @@ export namespace Docs {
         }
 
         export function WebDocument(url: string, options: DocumentOptions = {}) {
-            return InstanceFromProto(Prototypes.get(DocumentType.WEB), url ? new WebField(new URL(url)) : undefined, { _fitWidth: true, _chromeStatus: url ? "disabled" : "enabled", isAnnotating: true, lockedTransform: true, ...options });
+            return InstanceFromProto(Prototypes.get(DocumentType.WEB), url ? new WebField(new URL(url)) : undefined, { _fitWidth: true, _chromeStatus: url ? "disabled" : "enabled", isAnnotating: true, _lockedTransform: true, ...options });
         }
 
         export function HtmlDocument(html: string, options: DocumentOptions = {}) {
diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx
index d91337ce9..a0b7cd8a8 100644
--- a/src/client/views/collections/CollectionMapView.tsx
+++ b/src/client/views/collections/CollectionMapView.tsx
@@ -226,7 +226,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<IMapProps>
                     initialCenter={center}
                     center={center}
                     onIdle={(_props?: IMapProps, map?: google.maps.Map) => {
-                        if (this.layoutDoc.lockedTransform) {
+                        if (this.layoutDoc._lockedTransform) {
                             // reset zoom (ideally, we could probably can tell the map to disallow zooming somehow instead)
                             map?.setZoom(center?.zoom || 10);
                             map?.setCenter({ lat: center?.lat!, lng: center?.lng! });
@@ -238,7 +238,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<IMapProps>
                         }
                     }}
                     onDragend={(_props?: IMapProps, map?: google.maps.Map) => {
-                        if (this.layoutDoc.lockedTransform) {
+                        if (this.layoutDoc._lockedTransform) {
                             // reset the drag (ideally, we could probably can tell the map to disallow dragging somehow instead)
                             map?.setCenter({ lat: center?.lat!, lng: center?.lng! });
                         } else {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index c9b3519aa..972c09484 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -769,7 +769,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
 
     @action
     onPointerWheel = (e: React.WheelEvent): void => {
-        if (this.props.Document.lockedTransform || this.props.Document.inOverlay) return;
+        if (this.layoutDoc._lockedTransform || this.props.Document.inOverlay) return;
         if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming
             e.stopPropagation();
         }
@@ -805,7 +805,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                 else if (ranges.yrange.max <= (panY - panelDim[1] / 2)) panY = ranges.yrange.min - panelDim[1] / 2;
             }
         }
-        if (!this.Document.lockedTransform || this.Document.inOverlay) {
+        if (!this.layoutDoc._lockedTransform || this.Document.inOverlay) {
             this.Document.panTransformType = panType;
             const scale = this.getLocalTransform().inverse().Scale;
             const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX));
@@ -1169,6 +1169,12 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         Doc.toggleNativeDimensions(this.layoutDoc, this.props.ContentScaling(), this.props.NativeWidth(), this.props.NativeHeight());
     }
 
+    @undoBatch
+    @action
+    toggleLockTransform = (): void => {
+        this.layoutDoc._lockedTransform = this.layoutDoc._lockedTransform ? undefined : true;
+    }
+
     private thumbIdentifier?: number;
 
     onContextMenu = (e: React.MouseEvent) => {
@@ -1189,6 +1195,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         optionItems.push({ description: `${this.fitToContent ? "Unset" : "Set"} Fit To Container`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
         optionItems.push({ description: `${this.Document.useClusters ? "Uncluster" : "Use Clusters"}`, event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" });
         this.props.ContainingCollectionView && optionItems.push({ description: "Promote Collection", event: this.promoteCollection, icon: "table" });
+        optionItems.push({ description: this.layoutDoc._lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: this.layoutDoc._lockedTransform ? "unlock" : "lock" });
         optionItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" });
         // layoutItems.push({ description: "Analyze Strokes", event: this.analyzeStrokes, icon: "paint-brush" });
         optionItems.push({
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 34aabfe5e..8dbd0232b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -683,12 +683,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         this.Document.lockedPosition = this.Document.lockedPosition ? undefined : true;
     }
 
-    @undoBatch
-    @action
-    toggleLockTransform = (): void => {
-        this.Document.lockedTransform = this.Document.lockedTransform ? undefined : true;
-    }
-
     @action
     onContextMenu = async (e: React.MouseEvent | Touch): Promise<void> => {
         // the touch onContextMenu is button 0, the pointer onContextMenu is button 2
@@ -751,7 +745,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const moreItems: ContextMenuProps[] = more && "subitems" in more ? more.subitems : [];
         moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" });
         moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" });
-        moreItems.push({ description: this.Document.lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" });
         moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" });
 
         if (!ClientUtils.RELEASE) {
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index c1a585bca..1d242d958 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -59,14 +59,19 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
             iframe.contentDocument.addEventListener('scroll', this.iframeScrolled, false);
             this.layoutDoc.scrollHeight = iframe.contentDocument.children?.[0].scrollHeight || 1000;
             iframe.contentDocument.children[0].scrollTop = NumCast(this.layoutDoc.scrollTop);
+            iframe.contentDocument.children[0].scrollLeft = NumCast(this.layoutDoc.scrollLeft);
         }
         this._reactionDisposer?.();
-        this._reactionDisposer = reaction(() => this.layoutDoc.scrollY,
-            (scrollY) => {
-                if (scrollY !== undefined) {
-                    this._outerRef.current!.scrollTop = scrollY;
+        this._reactionDisposer = reaction(() => ({ y: this.layoutDoc.scrollY, x: this.layoutDoc.scrollX }),
+            ({ x, y }) => {
+                if (y !== undefined) {
+                    this._outerRef.current!.scrollTop = y;
                     this.layoutDoc.scrollY = undefined;
                 }
+                if (x !== undefined) {
+                    this._outerRef.current!.scrollLeft = x;
+                    this.layoutDoc.scrollX = undefined;
+                }
             },
             { fireImmediately: true }
         );
@@ -76,8 +81,10 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         this._setPreviewCursor?.(e.screenX, e.screenY, false);
     }
     iframeScrolled = (e: any) => {
-        const scroll = e.target?.children?.[0].scrollTop;
-        this.layoutDoc.scrollTop = this._outerRef.current!.scrollTop = scroll;
+        const scrollTop = e.target?.children?.[0].scrollTop;
+        const scrollLeft = e.target?.children?.[0].scrollLeft;
+        this.layoutDoc.scrollTop = this._outerRef.current!.scrollTop = scrollTop;
+        this.layoutDoc.scrollLeft = this._outerRef.current!.scrollLeft = scrollLeft;
     }
     async componentDidMount() {
         const urlField = Cast(this.dataDoc[this.props.fieldKey], WebField);
@@ -182,14 +189,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
     }
 
     toggleAnnotationMode = () => {
-        if (!this.layoutDoc.isAnnotating) {
-            this.layoutDoc.lockedTransform = false;
-            this.layoutDoc.isAnnotating = true;
-        }
-        else {
-            this.layoutDoc.lockedTransform = true;
-            this.layoutDoc.isAnnotating = false;
-        }
+        this.layoutDoc.isAnnotating = !this.layoutDoc.isAnnotating;
     }
 
     urlEditor() {
@@ -427,7 +427,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
             {this.urlEditor()}
         </>);
     }
-    scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.props.Document.scrollTop));
+    scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc.scrollLeft), NumCast(this.layoutDoc.scrollTop));
     render() {
         return (<div className={`webBox-container`}
             style={{
@@ -449,10 +449,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                         if (iframe.children[0].scrollTop !== outerFrame.scrollTop) {
                             iframe.children[0].scrollTop = outerFrame.scrollTop;
                         }
+                        if (iframe.children[0].scrollLeft !== outerFrame.scrollLeft) {
+                            iframe.children[0].scrollLeft = outerFrame.scrollLeft;
+                        }
                     }
                     //this._outerRef.current!.scrollTop !== this._scrollTop && (this._outerRef.current!.scrollTop = this._scrollTop)
                 }}>
-                <div className={"webBox-innerContent"} style={{ height: NumCast(this.layoutDoc.scrollHeight) }}>
+                <div className={"webBox-innerContent"} style={{ height: NumCast(this.layoutDoc.scrollHeight), width: 4000 }}>
                     <CollectionFreeFormView {...this.props}
                         PanelHeight={this.props.PanelHeight}
                         PanelWidth={this.props.PanelWidth}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index c50969493..810ce5aea 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -125,7 +125,6 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
 
     _lastSearch: string = "";
     componentDidMount = async () => {
-        !this.props.Document.lockedTransform && (this.props.Document.lockedTransform = true);
         // change the address to be the file address of the PNG version of each page
         // file address of the pdf
         const { url: { href } } = Cast(this.dataDoc[this.props.fieldKey], PdfField)!;
diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts
index cacba43b6..142f7e079 100644
--- a/src/fields/documentSchemas.ts
+++ b/src/fields/documentSchemas.ts
@@ -20,7 +20,9 @@ export const documentSchema = createSchema({
     z: "number",                // z "coordinate" - non-zero specifies the overlay layer of a freeformview
     zIndex: "number",           // zIndex of a document in a freeform view
     scrollY: "number",          // "command" to scroll a document to a position on load (the value will be reset to 0 after that )
+    scrollX: "number",          // "command" to scroll a document to a position on load (the value will be reset to 0 after that )
     scrollTop: "number",        // scroll position of a scrollable document (pdf, text, web)
+    scrollLeft: "number",        // scroll position of a scrollable document (pdf, text, web)
 
     // appearance properties on the layout
     _autoHeight: "boolean",     // whether the height of the document should be computed automatically based on its contents
@@ -74,8 +76,8 @@ export const documentSchema = createSchema({
     isLinkButton: "boolean",    // whether document functions as a link follow button to follow the first link on the document when clicked   
     isBackground: "boolean",    // whether document is a background element and ignores input events (can only select with marquee)
     lockedPosition: "boolean",  // whether the document can be moved (dragged)
-    lockedTransform: "boolean", // whether the document can be panned/zoomed
-
+    _lockedTransform: "boolean",// whether a freeformview can pan/zoom
+    
     // drag drop properties
     dragFactory: Doc,           // the document that serves as the "template" for the onDragStart script.  ie, to drag out copies of the dragFactory document.
     dropAction: "string",       // override specifying what should happen when this document is dropped (can be "alias", "copy", "move")
-- 
cgit v1.2.3-70-g09d2


From 45386f6950e5ae8390486900a430061bfe9e4846 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 21 May 2020 00:37:12 -0400
Subject: added animation to comparisonBox, cleaned up some npm modules

---
 package-lock.json                                  | 2578 +++++---------------
 package.json                                       |  116 +-
 src/client/util/SelectionManager.ts                |    2 -
 src/client/views/MainView.tsx                      |    4 +-
 .../views/collections/CollectionDockingView.tsx    |    3 -
 .../collections/CollectionMasonryViewFieldRow.tsx  |    4 -
 .../views/nodes/CollectionFreeFormDocumentView.tsx |    1 -
 src/client/views/nodes/ComparisonBox.scss          |    4 +-
 src/client/views/nodes/ComparisonBox.tsx           |   56 +-
 src/client/views/nodes/DocumentView.tsx            |    1 -
 src/client/views/nodes/ImageBox.tsx                |    1 -
 src/client/views/nodes/LabelBox.tsx                |    5 -
 src/client/views/nodes/PresBox.tsx                 |    5 +-
 src/client/views/nodes/VideoBox.tsx                |    9 +-
 src/client/views/search/CheckBox.tsx               |    1 -
 tsconfig.json                                      |    6 +
 16 files changed, 729 insertions(+), 2067 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/package-lock.json b/package-lock.json
index 9f9db7cfc..2e83c295c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,47 @@
                 "@babel/highlight": "^7.8.3"
             }
         },
+        "@babel/generator": {
+            "version": "7.9.6",
+            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz",
+            "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==",
+            "requires": {
+                "@babel/types": "^7.9.6",
+                "jsesc": "^2.5.1",
+                "lodash": "^4.17.13",
+                "source-map": "^0.5.0"
+            },
+            "dependencies": {
+                "@babel/types": {
+                    "version": "7.9.6",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
+                    "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.9.5",
+                        "lodash": "^4.17.13",
+                        "to-fast-properties": "^2.0.0"
+                    }
+                }
+            }
+        },
+        "@babel/helper-function-name": {
+            "version": "7.9.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz",
+            "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==",
+            "requires": {
+                "@babel/helper-get-function-arity": "^7.8.3",
+                "@babel/template": "^7.8.3",
+                "@babel/types": "^7.9.5"
+            }
+        },
+        "@babel/helper-get-function-arity": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
+            "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
+            "requires": {
+                "@babel/types": "^7.8.3"
+            }
+        },
         "@babel/helper-module-imports": {
             "version": "7.8.3",
             "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz",
@@ -20,6 +61,14 @@
                 "@babel/types": "^7.8.3"
             }
         },
+        "@babel/helper-split-export-declaration": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
+            "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
+            "requires": {
+                "@babel/types": "^7.8.3"
+            }
+        },
         "@babel/helper-validator-identifier": {
             "version": "7.9.5",
             "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
@@ -35,6 +84,11 @@
                 "js-tokens": "^4.0.0"
             }
         },
+        "@babel/parser": {
+            "version": "7.9.6",
+            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
+            "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q=="
+        },
         "@babel/runtime": {
             "version": "7.9.2",
             "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz",
@@ -52,6 +106,52 @@
                 "regenerator-runtime": "^0.13.4"
             }
         },
+        "@babel/template": {
+            "version": "7.8.6",
+            "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz",
+            "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==",
+            "requires": {
+                "@babel/code-frame": "^7.8.3",
+                "@babel/parser": "^7.8.6",
+                "@babel/types": "^7.8.6"
+            }
+        },
+        "@babel/traverse": {
+            "version": "7.9.6",
+            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz",
+            "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==",
+            "requires": {
+                "@babel/code-frame": "^7.8.3",
+                "@babel/generator": "^7.9.6",
+                "@babel/helper-function-name": "^7.9.5",
+                "@babel/helper-split-export-declaration": "^7.8.3",
+                "@babel/parser": "^7.9.6",
+                "@babel/types": "^7.9.6",
+                "debug": "^4.1.0",
+                "globals": "^11.1.0",
+                "lodash": "^4.17.13"
+            },
+            "dependencies": {
+                "@babel/types": {
+                    "version": "7.9.6",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
+                    "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.9.5",
+                        "lodash": "^4.17.13",
+                        "to-fast-properties": "^2.0.0"
+                    }
+                },
+                "debug": {
+                    "version": "4.1.1",
+                    "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+                    "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+                    "requires": {
+                        "ms": "^2.1.1"
+                    }
+                }
+            }
+        },
         "@babel/types": {
             "version": "7.9.5",
             "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz",
@@ -120,19 +220,6 @@
             "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz",
             "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA=="
         },
-        "@fortawesome/fontawesome-common-types": {
-            "version": "0.1.7",
-            "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.1.7.tgz",
-            "integrity": "sha512-ego8jRVSHfq/iq4KRZJKQeUAdi3ZjGNrqw4oPN3fNdvTBnLCSntwVCnc37bsAJP9UB8MhrTfPnZYxkv2vpS4pg=="
-        },
-        "@fortawesome/fontawesome-free-solid": {
-            "version": "5.0.13",
-            "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free-solid/-/fontawesome-free-solid-5.0.13.tgz",
-            "integrity": "sha512-b+krVnqkdDt52Yfev0x0ZZgtxBQsLw00Zfa3uaVWIDzpNZVtrEXuxldUSUaN/ihgGhSNi8VpvDAdNPVgCKOSxw==",
-            "requires": {
-                "@fortawesome/fontawesome-common-types": "^0.1.7"
-            }
-        },
         "@fortawesome/fontawesome-svg-core": {
             "version": "1.2.28",
             "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.28.tgz",
@@ -148,21 +235,6 @@
                 }
             }
         },
-        "@fortawesome/free-brands-svg-icons": {
-            "version": "5.13.0",
-            "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.13.0.tgz",
-            "integrity": "sha512-/6xXiJFCMEQxqxXbL0FPJpwq5Cv6MRrjsbJEmH/t5vOvB4dILDpnY0f7zZSlA8+TG7jwlt12miF/yZpZkykucA==",
-            "requires": {
-                "@fortawesome/fontawesome-common-types": "^0.2.28"
-            },
-            "dependencies": {
-                "@fortawesome/fontawesome-common-types": {
-                    "version": "0.2.28",
-                    "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.28.tgz",
-                    "integrity": "sha512-gtis2/5yLdfI6n0ia0jH7NJs5i/Z/8M/ZbQL6jXQhCthEOe5Cr5NcQPhgTvFxNOtURE03/ZqUcEskdn2M+QaBg=="
-                }
-            }
-        },
         "@fortawesome/free-regular-svg-icons": {
             "version": "5.13.0",
             "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.13.0.tgz",
@@ -243,97 +315,16 @@
             "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz",
             "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw=="
         },
-        "@jest/types": {
-            "version": "24.9.0",
-            "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz",
-            "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==",
-            "requires": {
-                "@types/istanbul-lib-coverage": "^2.0.0",
-                "@types/istanbul-reports": "^1.1.1",
-                "@types/yargs": "^13.0.0"
-            }
-        },
         "@log4js-node/log4js-api": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/@log4js-node/log4js-api/-/log4js-api-1.0.2.tgz",
             "integrity": "sha512-6SJfx949YEWooh/CUPpJ+F491y4BYJmknz4hUN1+RHvKoUEynKbRmhnwbk/VLmh4OthLLDNCyWXfbh4DG1cTXA=="
         },
-        "@popperjs/core": {
-            "version": "2.4.0",
-            "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.4.0.tgz",
-            "integrity": "sha512-NMrDy6EWh9TPdSRiHmHH2ye1v5U0gBD7pRYwSwJvomx7Bm4GG04vu63dYiVzebLOx2obPpJugew06xVP0Nk7hA=="
-        },
-        "@restart/context": {
-            "version": "2.1.4",
-            "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz",
-            "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q=="
-        },
-        "@restart/hooks": {
-            "version": "0.3.22",
-            "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.22.tgz",
-            "integrity": "sha512-tW0T3hP6emYNOc76/iC96rlu+f7JYLSVk/Wnn+7dj1gJUcw4CkQNLy16vx2mBLtVKsFMZ9miVEZXat8blruDHQ==",
-            "requires": {
-                "lodash": "^4.17.15",
-                "lodash-es": "^4.17.15"
-            }
-        },
-        "@tensorflow-models/universal-sentence-encoder": {
-            "version": "1.2.2",
-            "resolved": "https://registry.npmjs.org/@tensorflow-models/universal-sentence-encoder/-/universal-sentence-encoder-1.2.2.tgz",
-            "integrity": "sha512-fGCl/gwB7jmKCRI2FhgIBeIa/LCSUcjlEcckH2Bc2dIjhJ+2nspp+22lubxcseN6jjrmP42kkXt/reAPe+KJkQ=="
-        },
-        "@tensorflow/tfjs-converter": {
-            "version": "1.7.4",
-            "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-1.7.4.tgz",
-            "integrity": "sha512-B/Ux9I3osI0CXoESGR0Xe5C6BsEfC04+g2xn5zVaW9KEuVEnGEgnuBQxgijRFzkqTwoyLv4ptAmjyIghVARX0Q=="
-        },
-        "@tensorflow/tfjs-core": {
-            "version": "1.7.4",
-            "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-1.7.4.tgz",
-            "integrity": "sha512-3G4VKJ6nPs7iCt6gs3bjRj8chihKrYWenf63R0pm7D9MhlrVoX/tpN4LYVMGgBL7jHPxMLKdOkoAZJrn/J88HQ==",
-            "requires": {
-                "@types/offscreencanvas": "~2019.3.0",
-                "@types/seedrandom": "2.4.27",
-                "@types/webgl-ext": "0.0.30",
-                "@types/webgl2": "0.0.4",
-                "node-fetch": "~2.1.2",
-                "seedrandom": "2.4.3"
-            },
-            "dependencies": {
-                "node-fetch": {
-                    "version": "2.1.2",
-                    "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
-                    "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U="
-                }
-            }
-        },
-        "@trendmicro/react-buttons": {
-            "version": "1.3.1",
-            "resolved": "https://registry.npmjs.org/@trendmicro/react-buttons/-/react-buttons-1.3.1.tgz",
-            "integrity": "sha512-9zvt/fdkqCb9kxUdZnvTZKmbmykM2wDQ3VEJFtztGcKAkm4Wkq4oZOQLJXKfUQ1vX3w+YDJob18LkNOzaHI1UQ==",
-            "requires": {
-                "classnames": "^2.2.5",
-                "prop-types": "^15.5.8"
-            }
-        },
-        "@trendmicro/react-dropdown": {
-            "version": "1.4.0",
-            "resolved": "https://registry.npmjs.org/@trendmicro/react-dropdown/-/react-dropdown-1.4.0.tgz",
-            "integrity": "sha512-tXNUQ94MHdo4CqS2yq+M8bx4EkqEBbGE5OHQ7KwmGAYRyE6dvV+cULW8BJUwrVf/nQeOKZKcGwLLUD8NZ5Xpew==",
-            "requires": {
-                "@trendmicro/react-buttons": "^1.3.0",
-                "chained-function": "^0.5.0",
-                "classnames": "^2.2.5",
-                "dom-helpers": "^3.3.1",
-                "prop-types": "^15.6.0",
-                "uncontrollable": "^7.0.0",
-                "warning": "^3.0.0"
-            }
-        },
         "@types/adm-zip": {
             "version": "0.4.33",
             "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.4.33.tgz",
             "integrity": "sha512-WM0DCWFLjXtddl0fu0+iN2ZF+qz8RF9RddG5OSy/S90AQz01Fu8lHn/3oTIZDxvG8gVcnBLAHMHOdBLbV6m6Mw==",
+            "dev": true,
             "requires": {
                 "@types/node": "*"
             }
@@ -341,17 +332,20 @@
         "@types/animejs": {
             "version": "2.0.2",
             "resolved": "https://registry.npmjs.org/@types/animejs/-/animejs-2.0.2.tgz",
-            "integrity": "sha512-ACymFQ5qgSrZNR1Fqjk7Wv9gH6dFgejn2gpLkkceWxTKzivRJsshX4xhBVALgvF79gUdXiMCRIdusN728XpeGA=="
+            "integrity": "sha512-ACymFQ5qgSrZNR1Fqjk7Wv9gH6dFgejn2gpLkkceWxTKzivRJsshX4xhBVALgvF79gUdXiMCRIdusN728XpeGA==",
+            "dev": true
         },
         "@types/anymatch": {
             "version": "1.3.1",
             "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
-            "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA=="
+            "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==",
+            "dev": true
         },
         "@types/archiver": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-3.1.0.tgz",
             "integrity": "sha512-nTvHwgWONL+iXG+9CX+gnQ/tTOV+qucAjwpXqeUn4OCRMxP42T29FFP/7XaOo0EqqO3TlENhObeZEe7RUJAriw==",
+            "dev": true,
             "requires": {
                 "@types/glob": "*"
             }
@@ -359,35 +353,26 @@
         "@types/async": {
             "version": "2.4.2",
             "resolved": "https://registry.npmjs.org/@types/async/-/async-2.4.2.tgz",
-            "integrity": "sha512-bWBbC7VG2jdjbgZMX0qpds8U/3h3anfIqE81L8jmVrgFZw/urEDnBA78ymGGKTTK6ciBXmmJ/xlok+Re41S8ww=="
-        },
-        "@types/babel-types": {
-            "version": "7.0.7",
-            "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.7.tgz",
-            "integrity": "sha512-dBtBbrc+qTHy1WdfHYjBwRln4+LWqASWakLHsWHR2NWHIFkv4W3O070IGoGLEBrJBvct3r0L1BUPuvURi7kYUQ=="
-        },
-        "@types/babylon": {
-            "version": "6.16.5",
-            "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.5.tgz",
-            "integrity": "sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w==",
-            "requires": {
-                "@types/babel-types": "*"
-            }
+            "integrity": "sha512-bWBbC7VG2jdjbgZMX0qpds8U/3h3anfIqE81L8jmVrgFZw/urEDnBA78ymGGKTTK6ciBXmmJ/xlok+Re41S8ww==",
+            "dev": true
         },
         "@types/bcrypt-nodejs": {
             "version": "0.0.30",
             "resolved": "https://registry.npmjs.org/@types/bcrypt-nodejs/-/bcrypt-nodejs-0.0.30.tgz",
-            "integrity": "sha1-TN2WtJKTs5MhIuS34pVD415rrlg="
+            "integrity": "sha1-TN2WtJKTs5MhIuS34pVD415rrlg=",
+            "dev": true
         },
         "@types/bluebird": {
             "version": "3.5.30",
             "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.30.tgz",
-            "integrity": "sha512-8LhzvcjIoqoi1TghEkRMkbbmM+jhHnBokPGkJWjclMK+Ks0MxEBow3/p2/iFTZ+OIbJHQDSfpgdZEb+af3gfVw=="
+            "integrity": "sha512-8LhzvcjIoqoi1TghEkRMkbbmM+jhHnBokPGkJWjclMK+Ks0MxEBow3/p2/iFTZ+OIbJHQDSfpgdZEb+af3gfVw==",
+            "dev": true
         },
         "@types/body-parser": {
             "version": "1.19.0",
             "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
             "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==",
+            "dev": true,
             "requires": {
                 "@types/connect": "*",
                 "@types/node": "*"
@@ -397,6 +382,7 @@
             "version": "4.0.2",
             "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.2.tgz",
             "integrity": "sha512-+uWmsejEHfmSjyyM/LkrP0orfE2m5Mx9Xel4tXNeqi1ldK5XMQcDsFkBmLDtuyKUbxj2jGDo0H240fbCRJZo7Q==",
+            "dev": true,
             "requires": {
                 "@types/node": "*"
             }
@@ -404,7 +390,8 @@
         "@types/caseless": {
             "version": "0.12.2",
             "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz",
-            "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w=="
+            "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==",
+            "dev": true
         },
         "@types/chai": {
             "version": "4.2.11",
@@ -412,15 +399,11 @@
             "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==",
             "dev": true
         },
-        "@types/classnames": {
-            "version": "2.2.10",
-            "resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.10.tgz",
-            "integrity": "sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ=="
-        },
         "@types/color": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.1.tgz",
             "integrity": "sha512-oeUWVaAwI+xINDUx+3F2vJkl/vVB03VChFF/Gl3iQCdbcakjuoJyMOba+3BXRtnBhxZ7uBYqQBi9EpLnvSoztA==",
+            "dev": true,
             "requires": {
                 "@types/color-convert": "*"
             }
@@ -429,6 +412,7 @@
             "version": "1.9.0",
             "resolved": "https://registry.npmjs.org/@types/color-convert/-/color-convert-1.9.0.tgz",
             "integrity": "sha512-OKGEfULrvSL2VRbkl/gnjjgbbF7ycIlpSsX7Nkab4MOWi5XxmgBYvuiQ7lcCFY5cPDz7MUNaKgxte2VRmtr4Fg==",
+            "dev": true,
             "requires": {
                 "@types/color-name": "*"
             }
@@ -442,6 +426,7 @@
             "version": "3.4.33",
             "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz",
             "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==",
+            "dev": true,
             "requires": {
                 "@types/node": "*"
             }
@@ -450,6 +435,7 @@
             "version": "0.0.34",
             "resolved": "https://registry.npmjs.org/@types/connect-flash/-/connect-flash-0.0.34.tgz",
             "integrity": "sha512-QC93TwnTZ0sk//bfT81o7U4GOedbOZAcgvqi0v1vJqCESC8tqIVnhzB1CHiAUBUWFjoxG5JQF0TYaNa6DMb6Ig==",
+            "dev": true,
             "requires": {
                 "@types/express": "*"
             }
@@ -458,6 +444,7 @@
             "version": "1.4.2",
             "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.2.tgz",
             "integrity": "sha512-uwcY8m6SDQqciHsqcKDGbo10GdasYsPCYkH3hVegj9qAah6pX5HivOnOuI3WYmyQMnOATV39zv/Ybs0bC/6iVg==",
+            "dev": true,
             "requires": {
                 "@types/express": "*"
             }
@@ -466,20 +453,17 @@
             "version": "2.0.39",
             "resolved": "https://registry.npmjs.org/@types/cookie-session/-/cookie-session-2.0.39.tgz",
             "integrity": "sha512-Y35+TImpAvTAGswU89WuoWIioHUnbEgwFsR09ZC8n9qugEL18UVyIgQ0GvokspUnsWDoNtzQXD6hhDOGau38Rw==",
+            "dev": true,
             "requires": {
                 "@types/express": "*",
                 "@types/keygrip": "*"
             }
         },
-        "@types/d3-format": {
-            "version": "1.3.1",
-            "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-1.3.1.tgz",
-            "integrity": "sha512-KAWvReOKMDreaAwOjdfQMm0HjcUMlQG47GwqdVKgmm20vTd2pucj0a70c3gUSHrnsmo6H2AMrkBsZU2UhJLq8A=="
-        },
         "@types/dotenv": {
             "version": "6.1.1",
             "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-6.1.1.tgz",
             "integrity": "sha512-ftQl3DtBvqHl9L16tpqqzA4YzCSXZfi7g8cQceTz5rOlYtk/IZbFjAv3mLOQlNIgOaylCQWQoBdDQHPgEBJPHg==",
+            "dev": true,
             "requires": {
                 "@types/node": "*"
             }
@@ -487,12 +471,14 @@
         "@types/events": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
-            "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g=="
+            "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
+            "dev": true
         },
         "@types/exif": {
             "version": "0.6.0",
             "resolved": "https://registry.npmjs.org/@types/exif/-/exif-0.6.0.tgz",
             "integrity": "sha512-TyXIoevHn10FjPnCbNfpFlgb44c5KPsCbdWaNf59T76fKOl6YWfBQTmlt84kI7GtY4VuG9aW0qlEEmMuNDldoQ==",
+            "dev": true,
             "requires": {
                 "@types/node": "*"
             }
@@ -501,6 +487,7 @@
             "version": "4.17.6",
             "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.6.tgz",
             "integrity": "sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w==",
+            "dev": true,
             "requires": {
                 "@types/body-parser": "*",
                 "@types/express-serve-static-core": "*",
@@ -512,6 +499,7 @@
             "version": "0.0.0",
             "resolved": "https://registry.npmjs.org/@types/express-flash/-/express-flash-0.0.0.tgz",
             "integrity": "sha512-zs1xXRIZOjghUBriJPSnhPmfDpqf/EQxT21ggi/9XZ9/RHYrUi+5vK2jnQrP2pD1abbuZvm7owLICiNCLBQzEQ==",
+            "dev": true,
             "requires": {
                 "@types/connect-flash": "*",
                 "@types/express": "*"
@@ -521,6 +509,7 @@
             "version": "4.17.5",
             "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.5.tgz",
             "integrity": "sha512-578YH5Lt88AKoADy0b2jQGwJtrBxezXtVe/MBqWXKZpqx91SnC0pVkVCcxcytz3lWW+cHBYDi3Ysh0WXc+rAYw==",
+            "dev": true,
             "requires": {
                 "@types/node": "*",
                 "@types/range-parser": "*"
@@ -530,6 +519,7 @@
             "version": "1.17.0",
             "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.0.tgz",
             "integrity": "sha512-OQEHeBFE1UhChVIBhRh9qElHUvTp4BzKKHxMDkGHT7WuYk5eL93hPG7D8YAIkoBSbhNEY0RjreF15zn+U0eLjA==",
+            "dev": true,
             "requires": {
                 "@types/express": "*",
                 "@types/node": "*"
@@ -539,41 +529,26 @@
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/@types/express-validator/-/express-validator-3.0.0.tgz",
             "integrity": "sha512-LusnB0YhTXpBT25PXyGPQlK7leE1e41Vezq1hHEUwjfkopM1Pkv2X2Ppxqh9c+w/HZ6Udzki8AJotKNjDTGdkQ==",
+            "dev": true,
             "requires": {
                 "express-validator": "*"
             }
         },
-        "@types/extend": {
-            "version": "3.0.1",
-            "resolved": "https://registry.npmjs.org/@types/extend/-/extend-3.0.1.tgz",
-            "integrity": "sha512-R1g/VyKFFI2HLC1QGAeTtCBWCo6n75l41OnsVYNbmKG+kempOESaodf6BeJyUM3Q0rKa/NQcTHbB2+66lNnxLw=="
-        },
-        "@types/file-type": {
-            "version": "5.2.2",
-            "resolved": "https://registry.npmjs.org/@types/file-type/-/file-type-5.2.2.tgz",
-            "integrity": "sha512-GWtM4fyqfb+bec4ocpo51/y4x0b83Je+iA6eV131LT9wL0//G+1UgwbkMg7w61ceOwR+KkZXK00z44jrrNljWg==",
-            "requires": {
-                "@types/node": "*"
-            }
-        },
         "@types/formidable": {
             "version": "1.0.31",
             "resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-1.0.31.tgz",
             "integrity": "sha512-dIhM5t8lRP0oWe2HF8MuPvdd1TpPTjhDMAqemcq6oIZQCBQTovhBAdTQ5L5veJB4pdQChadmHuxtB0YzqvfU3Q==",
+            "dev": true,
             "requires": {
                 "@types/events": "*",
                 "@types/node": "*"
             }
         },
-        "@types/gapi": {
-            "version": "0.0.39",
-            "resolved": "https://registry.npmjs.org/@types/gapi/-/gapi-0.0.39.tgz",
-            "integrity": "sha512-R1TZeZbvvbIC60DBJMhuOEivQHzOQtzl3uMDOOENTYQTSSDB6oEMpJo8HVPOTWivdUTbyEcB5qQOVr/JCKRlCQ=="
-        },
         "@types/glob": {
             "version": "7.1.1",
             "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
             "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
+            "dev": true,
             "requires": {
                 "@types/events": "*",
                 "@types/minimatch": "*",
@@ -584,6 +559,7 @@
             "version": "2.0.4",
             "resolved": "https://registry.npmjs.org/@types/google-maps-react/-/google-maps-react-2.0.4.tgz",
             "integrity": "sha512-8EGr84L6ozODnfjWN9xVUFIxFedBbZinuDe5lBEJ757yh/lZqoKkqxrYLqvrLksDRVVwQYwWdFvfEASujmk36A==",
+            "dev": true,
             "requires": {
                 "@types/googlemaps": "*",
                 "@types/react": "*"
@@ -592,76 +568,29 @@
         "@types/googlemaps": {
             "version": "3.39.3",
             "resolved": "https://registry.npmjs.org/@types/googlemaps/-/googlemaps-3.39.3.tgz",
-            "integrity": "sha512-L8O9HAVFZj0TuiS8h5ORthiMsrrhjxTC8XUusp5k47oXCst4VTm+qWKvrAvmYMybZVokbp4Udco1mNwJrTNZPQ=="
-        },
-        "@types/isstream": {
-            "version": "0.1.0",
-            "resolved": "https://registry.npmjs.org/@types/isstream/-/isstream-0.1.0.tgz",
-            "integrity": "sha512-jo6R5XtVMgu1ej3H4o9NXiUE/4ZxyxmDrGslGiBa4/ugJr+Olw2viio/F2Vlc+zrwC9HJzuApOCCVC2g5jqV0w=="
-        },
-        "@types/istanbul-lib-coverage": {
-            "version": "2.0.1",
-            "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz",
-            "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg=="
-        },
-        "@types/istanbul-lib-report": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
-            "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
-            "requires": {
-                "@types/istanbul-lib-coverage": "*"
-            }
-        },
-        "@types/istanbul-reports": {
-            "version": "1.1.1",
-            "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz",
-            "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==",
-            "requires": {
-                "@types/istanbul-lib-coverage": "*",
-                "@types/istanbul-lib-report": "*"
-            }
-        },
-        "@types/jest": {
-            "version": "24.9.1",
-            "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.9.1.tgz",
-            "integrity": "sha512-Fb38HkXSVA4L8fGKEZ6le5bB8r6MRWlOCZbVuWZcmOMSCd2wCYOwN1ibj8daIoV9naq7aaOZjrLCoCMptKU/4Q==",
-            "requires": {
-                "jest-diff": "^24.3.0"
-            }
+            "integrity": "sha512-L8O9HAVFZj0TuiS8h5ORthiMsrrhjxTC8XUusp5k47oXCst4VTm+qWKvrAvmYMybZVokbp4Udco1mNwJrTNZPQ==",
+            "dev": true
         },
         "@types/jquery": {
             "version": "3.3.36",
             "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.36.tgz",
             "integrity": "sha512-jHL8J5y5fJ0+C9zCTkeOvX4zqRnPug3r6JhAqAYl2YyBCYHiXTbZSH0MRCpayZADed5TigPjH92dEKczUFT2TQ==",
+            "dev": true,
             "requires": {
                 "@types/sizzle": "*"
             }
         },
-        "@types/jquery-awesome-cursor": {
-            "version": "0.3.0",
-            "resolved": "https://registry.npmjs.org/@types/jquery-awesome-cursor/-/jquery-awesome-cursor-0.3.0.tgz",
-            "integrity": "sha512-tNou39eBTgyQtQGzcynUblExZdZiDqg5xuorANsoIfwBRBZZpHOP8wT/iDSR/qSq2rsu1KuQEfoC8z2L9YSp8A==",
-            "requires": {
-                "@types/jquery": "*"
-            }
-        },
-        "@types/jsonwebtoken": {
-            "version": "8.3.9",
-            "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.3.9.tgz",
-            "integrity": "sha512-00rI8GbOKuRtoYxltFSRTVUXCRLbuYwln2/nUMPtFU9JGS7if+nnmLjeoFGmqsNCmblPLAaeQ/zMLVsHr6T5bg==",
-            "requires": {
-                "@types/node": "*"
-            }
-        },
         "@types/keygrip": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz",
-            "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw=="
+            "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==",
+            "dev": true
         },
         "@types/libxmljs": {
             "version": "0.18.6",
             "resolved": "https://registry.npmjs.org/@types/libxmljs/-/libxmljs-0.18.6.tgz",
             "integrity": "sha512-xVUs71CwL5wYYfx5oH344DYWdoE2hVWlnRxlXFYyA8BcueN+Ey/h4FyhzEikbIJSXBKyPpJKhGu5c3NOx15nww==",
+            "dev": true,
             "requires": {
                 "@types/node": "*"
             }
@@ -669,7 +598,8 @@
         "@types/lodash": {
             "version": "4.14.150",
             "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.150.tgz",
-            "integrity": "sha512-kMNLM5JBcasgYscD9x/Gvr6lTAv2NVgsKtet/hm93qMyf/D1pt+7jeEZklKJKxMVmXjxbRVQQGfqDSfipYCO6w=="
+            "integrity": "sha512-kMNLM5JBcasgYscD9x/Gvr6lTAv2NVgsKtet/hm93qMyf/D1pt+7jeEZklKJKxMVmXjxbRVQQGfqDSfipYCO6w==",
+            "dev": true
         },
         "@types/memory-fs": {
             "version": "0.3.2",
@@ -683,17 +613,20 @@
         "@types/mime": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz",
-            "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw=="
+            "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==",
+            "dev": true
         },
         "@types/minimatch": {
             "version": "3.0.3",
             "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
-            "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
+            "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+            "dev": true
         },
         "@types/mobile-detect": {
             "version": "1.3.4",
             "resolved": "https://registry.npmjs.org/@types/mobile-detect/-/mobile-detect-1.3.4.tgz",
             "integrity": "sha512-MGBTvT5c7aH8eX6szFYP3dWPryNLt5iGlo31XNaJtt8o6jsg6tjn99eEMq9l8T6cPZymsr+J4Jth8+/G/04ZDw==",
+            "dev": true,
             "requires": {
                 "mobile-detect": "*"
             }
@@ -708,6 +641,7 @@
             "version": "3.5.14",
             "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.5.14.tgz",
             "integrity": "sha512-6SBBf4/pFTPu+Xmio6A4JPv/zXbsS/h7d3SdhaXRfTdE8pPNKUfOG3Tn7O0sjcu7Nz0syorSiQE6CMcoQD15TQ==",
+            "dev": true,
             "requires": {
                 "@types/bson": "*",
                 "@types/node": "*"
@@ -717,6 +651,7 @@
             "version": "5.7.14",
             "resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.7.14.tgz",
             "integrity": "sha512-jdMhuIluxmPKP58juOvQEl1C0syqyG0LK19zP+FRha0gvlFUwttXr2uxX4pzTHcuu/V6omzia9iGeXCoTEOT+w==",
+            "dev": true,
             "requires": {
                 "@types/mongodb": "*",
                 "@types/node": "*"
@@ -731,6 +666,7 @@
             "version": "4.6.8",
             "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-4.6.8.tgz",
             "integrity": "sha512-IX1P3bxDP1VIdZf6/kIWYNmSejkYm9MOyMEtoDFi4DVzKjJ3kY4GhOcOAKs6lZRjqVVmF9UjPOZXuQczlpZThw==",
+            "dev": true,
             "requires": {
                 "@types/node": "*"
             }
@@ -739,19 +675,16 @@
             "version": "0.9.1",
             "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.1.tgz",
             "integrity": "sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A==",
+            "dev": true,
             "requires": {
                 "@types/node": "*"
             }
         },
-        "@types/offscreencanvas": {
-            "version": "2019.3.0",
-            "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.3.0.tgz",
-            "integrity": "sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q=="
-        },
         "@types/orderedmap": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/@types/orderedmap/-/orderedmap-1.0.0.tgz",
-            "integrity": "sha512-dxKo80TqYx3YtBipHwA/SdFmMMyLCnP+5mkEqN0eMjcTBzHkiiX0ES118DsjDBjvD+zeSsSU9jULTZ+frog+Gw=="
+            "integrity": "sha512-dxKo80TqYx3YtBipHwA/SdFmMMyLCnP+5mkEqN0eMjcTBzHkiiX0ES118DsjDBjvD+zeSsSU9jULTZ+frog+Gw==",
+            "dev": true
         },
         "@types/parse-json": {
             "version": "4.0.0",
@@ -762,6 +695,7 @@
             "version": "1.0.3",
             "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.3.tgz",
             "integrity": "sha512-nyztuxtDPQv9utCzU0qW7Gl8BY2Dn8BKlYAFFyxKipFxjaVd96celbkLCV/tRqqBUZ+JB8If3UfgV8347DTo3Q==",
+            "dev": true,
             "requires": {
                 "@types/express": "*"
             }
@@ -770,6 +704,7 @@
             "version": "2.0.3",
             "resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.3.tgz",
             "integrity": "sha512-6EUEGzEg4acwowvgR/yVZIj8S2Kkwc6JmlY2/wnM1wJHNz20o7s1TIGrxnah8ymLgJasYDpy95P3TMMqlmetPw==",
+            "dev": true,
             "requires": {
                 "@types/express": "*",
                 "@types/passport": "*",
@@ -780,6 +715,7 @@
             "version": "1.0.33",
             "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.33.tgz",
             "integrity": "sha512-+rn6ZIxje0jZ2+DAiWFI8vGG7ZFKB0hXx2cUdMmudSWsigSq6ES7Emso46r4HJk0qCgrZVfI8sJiM7HIYf4SbA==",
+            "dev": true,
             "requires": {
                 "@types/express": "*",
                 "@types/passport": "*",
@@ -790,6 +726,7 @@
             "version": "1.4.9",
             "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.9.tgz",
             "integrity": "sha512-QP0q+NVQOaIu2r0e10QWkiUA0Ya5mOBHRJN0UrI+LolMLOP1/VN4EVIpJ3xVwFo+xqNFRoFvFwJhBvKnk7kpUA==",
+            "dev": true,
             "requires": {
                 "@types/express": "*",
                 "@types/oauth": "*",
@@ -800,6 +737,7 @@
             "version": "0.2.35",
             "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.35.tgz",
             "integrity": "sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==",
+            "dev": true,
             "requires": {
                 "@types/express": "*",
                 "@types/passport": "*"
@@ -808,7 +746,8 @@
         "@types/pdfjs-dist": {
             "version": "2.1.3",
             "resolved": "https://registry.npmjs.org/@types/pdfjs-dist/-/pdfjs-dist-2.1.3.tgz",
-            "integrity": "sha512-aGyFfB4Q8QjaSR3cBTiJfnFXBU6SXQaBVM7ADfBaZzq4L7EGbjuSoqXfHJofZmLFBfKzZ9b+9nXO2FfUIsw77w=="
+            "integrity": "sha512-aGyFfB4Q8QjaSR3cBTiJfnFXBU6SXQaBVM7ADfBaZzq4L7EGbjuSoqXfHJofZmLFBfKzZ9b+9nXO2FfUIsw77w==",
+            "dev": true
         },
         "@types/prop-types": {
             "version": "15.7.3",
@@ -819,6 +758,7 @@
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/@types/prosemirror-commands/-/prosemirror-commands-1.0.1.tgz",
             "integrity": "sha512-GeE12m8VT9N1JrzoY//946IX8ZyQOLNmvryJ+BNQs/HvhmXW9EWOcWUE6OBRtxK7Y8SrzSOwx4XmqSgVmK3tGQ==",
+            "dev": true,
             "requires": {
                 "@types/prosemirror-model": "*",
                 "@types/prosemirror-state": "*",
@@ -829,6 +769,7 @@
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/@types/prosemirror-history/-/prosemirror-history-1.0.1.tgz",
             "integrity": "sha512-BYyPJlWDo3VEnWS5X2DCHXrrAKEjdbCe1DUjGL6R/8hmwMFe3iMJGYdBkOXU1FfkTpw7Z+PlwY/pMyeelVydmg==",
+            "dev": true,
             "requires": {
                 "@types/prosemirror-model": "*",
                 "@types/prosemirror-state": "*"
@@ -838,6 +779,7 @@
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/@types/prosemirror-inputrules/-/prosemirror-inputrules-1.0.2.tgz",
             "integrity": "sha512-bKFneQUPnkZmzCJ1uoitpKH6PFW0hc4q55NsC7mFUCvX0eZl0GRKxyfV47jkJbsbyUQoO/QFv0WwLDz2bo15sA==",
+            "dev": true,
             "requires": {
                 "@types/prosemirror-model": "*",
                 "@types/prosemirror-state": "*"
@@ -847,6 +789,7 @@
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/@types/prosemirror-keymap/-/prosemirror-keymap-1.0.1.tgz",
             "integrity": "sha512-8IjM8ySmoZps9Tn+aKfB4ZR6zoNOjeQfAc9YLQujYXHJB6tdGWV0cbTuoT4QmZOR1iecN1EJ6E9RiRUBk796kQ==",
+            "dev": true,
             "requires": {
                 "@types/prosemirror-state": "*",
                 "@types/prosemirror-view": "*"
@@ -856,6 +799,7 @@
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/@types/prosemirror-menu/-/prosemirror-menu-1.0.1.tgz",
             "integrity": "sha512-wVGc6G7uYRvjIuVwV0zKSLwntFH1wanFwM1fDkq2YcUrLhuj4zZ1i7IPe+yqSoPm7JfmjiDEgHXTpafmwLKJrA==",
+            "dev": true,
             "requires": {
                 "@types/prosemirror-model": "*",
                 "@types/prosemirror-state": "*",
@@ -866,22 +810,16 @@
             "version": "1.7.2",
             "resolved": "https://registry.npmjs.org/@types/prosemirror-model/-/prosemirror-model-1.7.2.tgz",
             "integrity": "sha512-2l+yXvidg3AUHN07mO4Jd8Q84fo6ksFsy7LHUurLYrZ74uTahBp2fzcO49AKZMzww2EulXJ40Kl/OFaQ/7A1fw==",
+            "dev": true,
             "requires": {
                 "@types/orderedmap": "*"
             }
         },
-        "@types/prosemirror-schema-basic": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/@types/prosemirror-schema-basic/-/prosemirror-schema-basic-1.0.1.tgz",
-            "integrity": "sha512-IOQAYf1urifbH+Zwbq5XfFOUMNCbEnvIqpuSAE8SUt00nDAoH62T/S8Qhu8LuF++KQbyXb7fdMp352zkPW9Hmw==",
-            "requires": {
-                "@types/prosemirror-model": "*"
-            }
-        },
         "@types/prosemirror-schema-list": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/@types/prosemirror-schema-list/-/prosemirror-schema-list-1.0.1.tgz",
             "integrity": "sha512-+iUYq+pj2wVHSThj0MjNDzkkGwq8aDQ6j0UJK8a0cNCL8v44Ftcx1noGPtBIEUJgitH960VnfBNoTWfQoQZfRA==",
+            "dev": true,
             "requires": {
                 "@types/orderedmap": "*",
                 "@types/prosemirror-model": "*",
@@ -892,6 +830,7 @@
             "version": "1.2.3",
             "resolved": "https://registry.npmjs.org/@types/prosemirror-state/-/prosemirror-state-1.2.3.tgz",
             "integrity": "sha512-6m433Hubix9bx+JgcLW7zzyiZuzwjq5mBdSMYY4Yi5c5ZpV2RiVmg7Cy6f9Thtts8vuztilw+PczJAgDm1Frfw==",
+            "dev": true,
             "requires": {
                 "@types/prosemirror-model": "*",
                 "@types/prosemirror-transform": "*",
@@ -902,6 +841,7 @@
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/@types/prosemirror-transform/-/prosemirror-transform-1.1.1.tgz",
             "integrity": "sha512-yYCYSoiRH+Wcbl8GJc0PFCzeyMzNQ1vL2xrHHSXZuNcIlH75VoiKrZFeZ6BS9cl8mYXjZrlmdBe8YOxYvyKM6A==",
+            "dev": true,
             "requires": {
                 "@types/prosemirror-model": "*"
             }
@@ -910,21 +850,18 @@
             "version": "1.11.4",
             "resolved": "https://registry.npmjs.org/@types/prosemirror-view/-/prosemirror-view-1.11.4.tgz",
             "integrity": "sha512-Hh8v2tpCEMaIesQuw7Y7Pz6imoC1T/bR5OlNGVtp944PZvctXiBvFRkQIb0YvZpt7vVkFzeq2kmR+7mnUfvWiw==",
+            "dev": true,
             "requires": {
                 "@types/prosemirror-model": "*",
                 "@types/prosemirror-state": "*",
                 "@types/prosemirror-transform": "*"
             }
         },
-        "@types/pug": {
-            "version": "2.0.4",
-            "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.4.tgz",
-            "integrity": "sha1-h3L80EGOPNLMFxVV1zAHQVBR9LI="
-        },
         "@types/puppeteer": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-2.1.0.tgz",
             "integrity": "sha512-QIRQXl0VaSgnwOZ1LwxD321Tfb1jLOzCWuF2BrwjEkWq2IhxSicPOddUywLV7dRSO6mcU4sWKRdoGdci6gk0Aw==",
+            "dev": true,
             "requires": {
                 "@types/node": "*"
             }
@@ -932,17 +869,20 @@
         "@types/qs": {
             "version": "6.9.1",
             "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.1.tgz",
-            "integrity": "sha512-lhbQXx9HKZAPgBkISrBcmAcMpZsmpe/Cd/hY7LGZS5OfkySUBItnPZHgQPssWYUET8elF+yCFBbP1Q0RZPTdaw=="
+            "integrity": "sha512-lhbQXx9HKZAPgBkISrBcmAcMpZsmpe/Cd/hY7LGZS5OfkySUBItnPZHgQPssWYUET8elF+yCFBbP1Q0RZPTdaw==",
+            "dev": true
         },
         "@types/range-parser": {
             "version": "1.2.3",
             "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
-            "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA=="
+            "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
+            "dev": true
         },
         "@types/rc-switch": {
             "version": "1.9.0",
             "resolved": "https://registry.npmjs.org/@types/rc-switch/-/rc-switch-1.9.0.tgz",
             "integrity": "sha512-L3ZQ2/1GAaiKuQTMO/2sRdhnNNVtnnvdE0ZOL3/+v54j5LguOvYqTSOHPk9nLPi5va3pdRN1MTce3JkJvGZ65A==",
+            "dev": true,
             "requires": {
                 "@types/react": "*"
             }
@@ -960,6 +900,7 @@
             "version": "9.3.13",
             "resolved": "https://registry.npmjs.org/@types/react-autosuggest/-/react-autosuggest-9.3.13.tgz",
             "integrity": "sha512-J1RB5KAIk6vOJ+TkIE+EqjCWBjXxjobzeA6D9KrS64kzrt6ixC6uSoKMFnG6ByeWoC+1g0756NILCpIpTV62dw==",
+            "dev": true,
             "requires": {
                 "@types/react": "*"
             }
@@ -968,6 +909,7 @@
             "version": "2.17.3",
             "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-2.17.3.tgz",
             "integrity": "sha512-ewFUB9mNXuqT2UMbiYNqXiUWt857VinGaElhX0Gk+kT1BrXel0imzRp1FeWntHpr+uHkKAnJbr5e4Yc4vP1BRg==",
+            "dev": true,
             "requires": {
                 "@types/react": "*"
             }
@@ -985,6 +927,7 @@
             "version": "2.0.6",
             "resolved": "https://registry.npmjs.org/@types/react-measure/-/react-measure-2.0.6.tgz",
             "integrity": "sha512-FxAwgDVKvxm4SPXu24x9cwzsty8x33UueazHcpxM1UWZlGJI57yIHM2djE3xUJhYVxuzNzi4E8UL3kmCkdh+4A==",
+            "dev": true,
             "requires": {
                 "@types/react": "*"
             }
@@ -1001,6 +944,7 @@
             "version": "2.48.4",
             "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.4.tgz",
             "integrity": "sha512-W1t1MTKYR8PxICH+A4HgEIPuAC3sbljoEVfyZbeFJJDbr30guDspJri2XOaM2E+Un7ZjrihaDi7cf6fPa2tbgw==",
+            "dev": true,
             "requires": {
                 "@types/caseless": "*",
                 "@types/node": "*",
@@ -1012,6 +956,7 @@
             "version": "4.1.46",
             "resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.46.tgz",
             "integrity": "sha512-3Thpj2Va5m0ji3spaCk8YKrjkZyZc6RqUVOphA0n/Xet66AW/AiOAs5vfXhQIL5NmkaO7Jnun7Nl9NEjJ2zBaw==",
+            "dev": true,
             "requires": {
                 "@types/bluebird": "*",
                 "@types/request": "*"
@@ -1021,20 +966,17 @@
             "version": "2.0.4",
             "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.4.tgz",
             "integrity": "sha512-8gBudvllD2A/c0CcEX/BivIDorHFt5UI5m46TsNj8DjWCCTTZT74kEe4g+QsY7P/B9WdO98d82zZgXO/RQzu2Q==",
+            "dev": true,
             "requires": {
                 "@types/glob": "*",
                 "@types/node": "*"
             }
         },
-        "@types/seedrandom": {
-            "version": "2.4.27",
-            "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.27.tgz",
-            "integrity": "sha1-nbVjk33YaRX2kJK8QyWdL0hXjkE="
-        },
         "@types/serve-static": {
             "version": "1.13.3",
             "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz",
             "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==",
+            "dev": true,
             "requires": {
                 "@types/express-serve-static-core": "*",
                 "@types/mime": "*"
@@ -1044,6 +986,7 @@
             "version": "0.23.1",
             "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.23.1.tgz",
             "integrity": "sha512-iBRM9RjRF9pkIkukk6imlxfaKMRuiRND8L0yYKl5PJu5uLvxuNzp5f0x8aoTG5VX85M8O//BwbttzFVZL1j/FQ==",
+            "dev": true,
             "requires": {
                 "@types/node": "*"
             }
@@ -1052,6 +995,7 @@
             "version": "0.8.7",
             "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.7.tgz",
             "integrity": "sha512-Mg2qGjLIJIieeJ1/NjswAOY9qXDShLeh6JwpD1NZsvUvI0hxdUCNDpnBXv9YQeugKi2EHU+BqkbUE4jpY4GKmQ==",
+            "dev": true,
             "requires": {
                 "@types/glob": "*",
                 "@types/node": "*"
@@ -1060,12 +1004,14 @@
         "@types/sizzle": {
             "version": "2.3.2",
             "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
-            "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg=="
+            "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==",
+            "dev": true
         },
         "@types/socket.io": {
             "version": "2.1.4",
             "resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-2.1.4.tgz",
             "integrity": "sha512-cI98INy7tYnweTsUlp8ocveVdAxENUThO0JsLSCs51cjOP2yV5Mqo5QszMDPckyRRA+PO6+wBgKvGvHUCc23TQ==",
+            "dev": true,
             "requires": {
                 "@types/node": "*"
             }
@@ -1073,12 +1019,14 @@
         "@types/socket.io-client": {
             "version": "1.4.32",
             "resolved": "https://registry.npmjs.org/@types/socket.io-client/-/socket.io-client-1.4.32.tgz",
-            "integrity": "sha512-Vs55Kq8F+OWvy1RLA31rT+cAyemzgm0EWNeax6BWF8H7QiiOYMJIdcwSDdm5LVgfEkoepsWkS+40+WNb7BUMbg=="
+            "integrity": "sha512-Vs55Kq8F+OWvy1RLA31rT+cAyemzgm0EWNeax6BWF8H7QiiOYMJIdcwSDdm5LVgfEkoepsWkS+40+WNb7BUMbg==",
+            "dev": true
         },
         "@types/source-list-map": {
             "version": "0.1.2",
             "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
-            "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA=="
+            "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==",
+            "dev": true
         },
         "@types/strip-bom": {
             "version": "3.0.0",
@@ -1095,17 +1043,20 @@
         "@types/tapable": {
             "version": "1.0.5",
             "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz",
-            "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ=="
+            "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==",
+            "dev": true
         },
         "@types/tough-cookie": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz",
-            "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A=="
+            "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==",
+            "dev": true
         },
         "@types/typescript": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/@types/typescript/-/typescript-2.0.0.tgz",
             "integrity": "sha1-xDNTnJi64oaCswfqp6D9IRW4PCg=",
+            "dev": true,
             "requires": {
                 "typescript": "*"
             }
@@ -1114,6 +1065,7 @@
             "version": "3.9.0",
             "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.0.tgz",
             "integrity": "sha512-3ZcoyPYHVOCcLpnfZwD47KFLr8W/mpUcgjpf1M4Q78TMJIw7KMAHSjiCLJp1z3ZrBR9pTLbe191O0TldFK5zcw==",
+            "dev": true,
             "requires": {
                 "source-map": "^0.6.1"
             },
@@ -1121,39 +1073,28 @@
                 "source-map": {
                     "version": "0.6.1",
                     "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-                    "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+                    "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+                    "dev": true
                 }
             }
         },
         "@types/uuid": {
             "version": "3.4.9",
             "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.9.tgz",
-            "integrity": "sha512-XDwyIlt/47l2kWLTzw/mtrpLdB+GPSskR2n/PIcPn+VYhVO77rGhRncIR5GPU0KRzXuqkDO+J5qqrG0Y8P6jzQ=="
+            "integrity": "sha512-XDwyIlt/47l2kWLTzw/mtrpLdB+GPSskR2n/PIcPn+VYhVO77rGhRncIR5GPU0KRzXuqkDO+J5qqrG0Y8P6jzQ==",
+            "dev": true
         },
         "@types/valid-url": {
             "version": "1.0.3",
             "resolved": "https://registry.npmjs.org/@types/valid-url/-/valid-url-1.0.3.tgz",
-            "integrity": "sha512-+33x29mg+ecU88ODdWpqaie2upIuRkhujVLA7TuJjM823cNMbeggfI6NhxewaRaRF8dy+g33e4uIg/m5Mb3xDQ=="
-        },
-        "@types/warning": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz",
-            "integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI="
-        },
-        "@types/webgl-ext": {
-            "version": "0.0.30",
-            "resolved": "https://registry.npmjs.org/@types/webgl-ext/-/webgl-ext-0.0.30.tgz",
-            "integrity": "sha512-LKVgNmBxN0BbljJrVUwkxwRYqzsAEPcZOe6S2T6ZaBDIrFp0qu4FNlpc5sM1tGbXUYFgdVQIoeLk1Y1UoblyEg=="
-        },
-        "@types/webgl2": {
-            "version": "0.0.4",
-            "resolved": "https://registry.npmjs.org/@types/webgl2/-/webgl2-0.0.4.tgz",
-            "integrity": "sha512-PACt1xdErJbMUOUweSrbVM7gSIYm1vTncW2hF6Os/EeWi6TXYAYMPp+8v6rzHmypE5gHrxaxZNXgMkJVIdZpHw=="
+            "integrity": "sha512-+33x29mg+ecU88ODdWpqaie2upIuRkhujVLA7TuJjM823cNMbeggfI6NhxewaRaRF8dy+g33e4uIg/m5Mb3xDQ==",
+            "dev": true
         },
         "@types/webpack": {
             "version": "4.41.12",
             "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.12.tgz",
             "integrity": "sha512-BpCtM4NnBen6W+KEhrL9jKuZCXVtiH6+0b6cxdvNt2EwU949Al334PjQSl2BeAyvAX9mgoNNG21wvjP3xZJJ5w==",
+            "dev": true,
             "requires": {
                 "@types/anymatch": "*",
                 "@types/node": "*",
@@ -1166,7 +1107,8 @@
                 "source-map": {
                     "version": "0.6.1",
                     "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-                    "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+                    "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+                    "dev": true
                 }
             }
         },
@@ -1195,6 +1137,7 @@
             "version": "0.1.7",
             "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz",
             "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==",
+            "dev": true,
             "requires": {
                 "@types/node": "*",
                 "@types/source-list-map": "*",
@@ -1204,40 +1147,16 @@
                 "source-map": {
                     "version": "0.6.1",
                     "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-                    "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+                    "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+                    "dev": true
                 }
             }
         },
-        "@types/websocket": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.0.tgz",
-            "integrity": "sha512-MLr8hDM8y7vvdAdnoDEP5LotRoYJj7wgT6mWzCUQH/gHqzS4qcnOT/K4dhC0WimWIUiA3Arj9QAJGGKNRiRZKA==",
-            "requires": {
-                "@types/node": "*"
-            }
-        },
-        "@types/word-extractor": {
-            "version": "0.3.0",
-            "resolved": "https://registry.npmjs.org/@types/word-extractor/-/word-extractor-0.3.0.tgz",
-            "integrity": "sha512-XcVsLXMpPT6Lv4Qvsc2yPoWg3zPVKEIyQ21eQ1ka58zZjtd7vUZ2kx0KydRbsNRNGopEIiwlemGzgo46dytR2Q=="
-        },
         "@types/xregexp": {
             "version": "4.3.0",
             "resolved": "https://registry.npmjs.org/@types/xregexp/-/xregexp-4.3.0.tgz",
-            "integrity": "sha512-3gJTS9gt27pS7U9q5IVqo4YvKSlkf2ck8ish6etuDj6LIRxkL/2Y8RMUtK/QzvE1Yv2zwWV5yemI2BS0GGGFnA=="
-        },
-        "@types/yargs": {
-            "version": "13.0.8",
-            "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz",
-            "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==",
-            "requires": {
-                "@types/yargs-parser": "*"
-            }
-        },
-        "@types/yargs-parser": {
-            "version": "15.0.0",
-            "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz",
-            "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw=="
+            "integrity": "sha512-3gJTS9gt27pS7U9q5IVqo4YvKSlkf2ck8ish6etuDj6LIRxkL/2Y8RMUtK/QzvE1Yv2zwWV5yemI2BS0GGGFnA==",
+            "dev": true
         },
         "@types/yauzl": {
             "version": "2.9.1",
@@ -1249,9 +1168,10 @@
             }
         },
         "@types/youtube": {
-            "version": "0.0.38",
-            "resolved": "https://registry.npmjs.org/@types/youtube/-/youtube-0.0.38.tgz",
-            "integrity": "sha512-rS0nLlnnZIvOfBNT4957rkKRMHjHxutoVhSEzowocYgNiTMVBmN+Hbkf/L3TeGMMtts9uKZ9gw7O2JLHREVnIw=="
+            "version": "0.0.39",
+            "resolved": "https://registry.npmjs.org/@types/youtube/-/youtube-0.0.39.tgz",
+            "integrity": "sha512-naVjyTZT/CoNwEQW3+mf9E/x6sgB7QIPbRDtVlPUpHlmuQTk+j6gQBy0T5CRkV8oC0GYQjMgfr3VdueTSVLTjw==",
+            "dev": true
         },
         "@webassemblyjs/ast": {
             "version": "1.9.0",
@@ -1468,26 +1388,6 @@
                 "negotiator": "0.6.2"
             }
         },
-        "acorn": {
-            "version": "5.7.4",
-            "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
-            "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg=="
-        },
-        "acorn-globals": {
-            "version": "3.1.0",
-            "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
-            "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
-            "requires": {
-                "acorn": "^4.0.4"
-            },
-            "dependencies": {
-                "acorn": {
-                    "version": "4.0.13",
-                    "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
-                    "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
-                }
-            }
-        },
         "acorn-jsx": {
             "version": "5.2.0",
             "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz",
@@ -1499,11 +1399,6 @@
             "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
             "dev": true
         },
-        "addressparser": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz",
-            "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y="
-        },
         "adm-zip": {
             "version": "0.4.14",
             "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.14.tgz",
@@ -1537,57 +1432,27 @@
             "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
             "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
             "requires": {
-                "fast-deep-equal": "^3.1.1",
-                "fast-json-stable-stringify": "^2.0.0",
-                "json-schema-traverse": "^0.4.1",
-                "uri-js": "^4.2.2"
-            }
-        },
-        "ajv-errors": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
-            "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ=="
-        },
-        "ajv-keywords": {
-            "version": "3.4.1",
-            "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz",
-            "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ=="
-        },
-        "align-text": {
-            "version": "0.1.4",
-            "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
-            "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
-            "requires": {
-                "kind-of": "^3.0.2",
-                "longest": "^1.0.1",
-                "repeat-string": "^1.5.2"
-            },
-            "dependencies": {
-                "is-buffer": {
-                    "version": "1.1.6",
-                    "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
-                    "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
-                },
-                "kind-of": {
-                    "version": "3.2.2",
-                    "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-                    "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-                    "requires": {
-                        "is-buffer": "^1.1.5"
-                    }
-                }
+                "fast-deep-equal": "^3.1.1",
+                "fast-json-stable-stringify": "^2.0.0",
+                "json-schema-traverse": "^0.4.1",
+                "uri-js": "^4.2.2"
             }
         },
+        "ajv-errors": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
+            "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ=="
+        },
+        "ajv-keywords": {
+            "version": "3.4.1",
+            "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz",
+            "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ=="
+        },
         "amdefine": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
             "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
         },
-        "animejs": {
-            "version": "3.2.0",
-            "resolved": "https://registry.npmjs.org/animejs/-/animejs-3.2.0.tgz",
-            "integrity": "sha512-zhtGl5cS0G2f5DfciMO8uwWpnx06nfFnHlXYYXHBazHep1Lyd6kEtBQP+9hpYKE0dBZjIigHp9VpMO95ZfXQJQ=="
-        },
         "ansi-align": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
@@ -1853,11 +1718,6 @@
             "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
             "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
         },
-        "array-indexofobject": {
-            "version": "0.0.1",
-            "resolved": "https://registry.npmjs.org/array-indexofobject/-/array-indexofobject-0.0.1.tgz",
-            "integrity": "sha1-qqEo5iybPDWAlFaMIZ/2T+SJ1Co="
-        },
         "array-union": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
@@ -1888,14 +1748,6 @@
             "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
             "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug=="
         },
-        "arxiv-api-node": {
-            "version": "0.0.2",
-            "resolved": "https://registry.npmjs.org/arxiv-api-node/-/arxiv-api-node-0.0.2.tgz",
-            "integrity": "sha512-vtFiygbvNK9UGYYgR7Ny1JMkamIl1q59nou8jpR0kTpJLTHc4FIGM9HTq3WyWHOMpBqffBpBbyL07cA4J2XLAg==",
-            "requires": {
-                "request": "^2.83.0"
-            }
-        },
         "asap": {
             "version": "2.0.6",
             "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
@@ -1913,6 +1765,7 @@
             "version": "4.10.1",
             "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
             "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+            "dev": true,
             "requires": {
                 "bn.js": "^4.0.0",
                 "inherits": "^2.0.1",
@@ -1961,11 +1814,6 @@
             "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
             "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
         },
-        "ast-types": {
-            "version": "0.9.6",
-            "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz",
-            "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk="
-        },
         "async": {
             "version": "2.6.3",
             "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
@@ -2025,43 +1873,6 @@
             "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
             "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug=="
         },
-        "axios": {
-            "version": "0.18.1",
-            "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz",
-            "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==",
-            "requires": {
-                "follow-redirects": "1.5.10",
-                "is-buffer": "^2.0.2"
-            }
-        },
-        "axios-cookiejar-support": {
-            "version": "0.5.1",
-            "resolved": "https://registry.npmjs.org/axios-cookiejar-support/-/axios-cookiejar-support-0.5.1.tgz",
-            "integrity": "sha512-mmMbNDjpkAKlyxVOYjkpvV6rDRoSjBXwHbfkWvnsplRTGYCergbHvZInRB1G3lqumllUQwo0A4uPoqEsYfzq3A==",
-            "requires": {
-                "@types/tough-cookie": "^2.3.3",
-                "is-redirect": "^1.0.0",
-                "pify": "^4.0.0",
-                "tough-cookie": "^3.0.1"
-            },
-            "dependencies": {
-                "@types/tough-cookie": {
-                    "version": "2.3.7",
-                    "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.7.tgz",
-                    "integrity": "sha512-rMQbgMGxnLsdn8e9aPVyuN+zMQLrZ2QW8xlv7eWS1mydfGXN+tsTKffcIzd8rGCcLdmi3xvQw2MDaZI1bBNTaw=="
-                },
-                "tough-cookie": {
-                    "version": "3.0.1",
-                    "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
-                    "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
-                    "requires": {
-                        "ip-regex": "^2.1.0",
-                        "psl": "^1.1.28",
-                        "punycode": "^2.1.1"
-                    }
-                }
-            }
-        },
         "babel-code-frame": {
             "version": "6.26.0",
             "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
@@ -2174,29 +1985,6 @@
                 }
             }
         },
-        "babel-types": {
-            "version": "6.26.0",
-            "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
-            "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
-            "requires": {
-                "babel-runtime": "^6.26.0",
-                "esutils": "^2.0.2",
-                "lodash": "^4.17.4",
-                "to-fast-properties": "^1.0.3"
-            },
-            "dependencies": {
-                "to-fast-properties": {
-                    "version": "1.0.3",
-                    "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
-                    "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc="
-                }
-            }
-        },
-        "babylon": {
-            "version": "6.18.0",
-            "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
-            "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
-        },
         "backo2": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
@@ -2257,11 +2045,6 @@
                 }
             }
         },
-        "base62": {
-            "version": "1.2.8",
-            "resolved": "https://registry.npmjs.org/base62/-/base62-1.2.8.tgz",
-            "integrity": "sha512-V6YHUbjLxN1ymqNLb1DPHoU1CpfdL7d2YTIp5W3U4hhoG4hhxNmsFDs66M9EXxBiSEke5Bt5dwdfMwwZF70iLA=="
-        },
         "base64-arraybuffer": {
             "version": "0.1.5",
             "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
@@ -2365,7 +2148,8 @@
         "bn.js": {
             "version": "4.11.8",
             "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-            "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+            "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+            "dev": true
         },
         "body-parser": {
             "version": "1.19.0",
@@ -2501,7 +2285,8 @@
         "brorand": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
-            "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
+            "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+            "dev": true
         },
         "browser-process-hrtime": {
             "version": "1.0.0",
@@ -2518,6 +2303,7 @@
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
             "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+            "dev": true,
             "requires": {
                 "buffer-xor": "^1.0.3",
                 "cipher-base": "^1.0.0",
@@ -2531,6 +2317,7 @@
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
             "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+            "dev": true,
             "requires": {
                 "browserify-aes": "^1.0.4",
                 "browserify-des": "^1.0.0",
@@ -2541,6 +2328,7 @@
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
             "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+            "dev": true,
             "requires": {
                 "cipher-base": "^1.0.1",
                 "des.js": "^1.0.0",
@@ -2552,6 +2340,7 @@
             "version": "4.0.1",
             "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
             "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+            "dev": true,
             "requires": {
                 "bn.js": "^4.1.0",
                 "randombytes": "^2.0.1"
@@ -2561,6 +2350,7 @@
             "version": "4.0.4",
             "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
             "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
+            "dev": true,
             "requires": {
                 "bn.js": "^4.1.1",
                 "browserify-rsa": "^4.0.0",
@@ -2580,14 +2370,6 @@
                 "pako": "~1.0.5"
             }
         },
-        "bs-logger": {
-            "version": "0.2.6",
-            "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
-            "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
-            "requires": {
-                "fast-json-stable-stringify": "2.x"
-            }
-        },
         "bson": {
             "version": "1.0.9",
             "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz",
@@ -2615,7 +2397,8 @@
         "buffer-from": {
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
-            "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
+            "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+            "dev": true
         },
         "buffer-indexof": {
             "version": "1.1.1",
@@ -2631,7 +2414,8 @@
         "buffer-xor": {
             "version": "1.0.3",
             "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
-            "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
+            "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+            "dev": true
         },
         "builtin-modules": {
             "version": "1.1.1",
@@ -2714,6 +2498,29 @@
                 "unset-value": "^1.0.0"
             }
         },
+        "caller-callsite": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+            "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
+            "requires": {
+                "callsites": "^2.0.0"
+            },
+            "dependencies": {
+                "callsites": {
+                    "version": "2.0.0",
+                    "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+                    "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA="
+                }
+            }
+        },
+        "caller-path": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+            "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
+            "requires": {
+                "caller-callsite": "^2.0.0"
+            }
+        },
         "callsite": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
@@ -2792,15 +2599,6 @@
             "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
             "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
         },
-        "center-align": {
-            "version": "0.1.3",
-            "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
-            "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
-            "requires": {
-                "align-text": "^0.1.3",
-                "lazy-cache": "^1.0.3"
-            }
-        },
         "chai": {
             "version": "4.2.0",
             "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
@@ -2814,11 +2612,6 @@
                 "type-detect": "^4.0.5"
             }
         },
-        "chained-function": {
-            "version": "0.5.0",
-            "resolved": "https://registry.npmjs.org/chained-function/-/chained-function-0.5.0.tgz",
-            "integrity": "sha1-JWS73994AxlL6/daayvQQe3iOzo="
-        },
         "chalk": {
             "version": "2.4.2",
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -2829,14 +2622,6 @@
                 "supports-color": "^5.3.0"
             }
         },
-        "character-parser": {
-            "version": "2.2.0",
-            "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
-            "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=",
-            "requires": {
-                "is-regex": "^1.0.3"
-            }
-        },
         "check-error": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
@@ -3388,6 +3173,7 @@
             "version": "1.0.4",
             "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
             "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+            "dev": true,
             "requires": {
                 "inherits": "^2.0.1",
                 "safe-buffer": "^5.0.1"
@@ -3424,21 +3210,6 @@
             "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
             "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
         },
-        "clean-css": {
-            "version": "4.2.3",
-            "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
-            "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==",
-            "requires": {
-                "source-map": "~0.6.0"
-            },
-            "dependencies": {
-                "source-map": {
-                    "version": "0.6.1",
-                    "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-                    "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
-                }
-            }
-        },
         "cli-boxes": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
@@ -3605,36 +3376,6 @@
             "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
             "dev": true
         },
-        "commoner": {
-            "version": "0.10.8",
-            "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz",
-            "integrity": "sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=",
-            "requires": {
-                "commander": "^2.5.0",
-                "detective": "^4.3.1",
-                "glob": "^5.0.15",
-                "graceful-fs": "^4.1.2",
-                "iconv-lite": "^0.4.5",
-                "mkdirp": "^0.5.0",
-                "private": "^0.1.6",
-                "q": "^1.1.2",
-                "recast": "^0.11.17"
-            },
-            "dependencies": {
-                "glob": {
-                    "version": "5.0.15",
-                    "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
-                    "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
-                    "requires": {
-                        "inflight": "^1.0.4",
-                        "inherits": "2",
-                        "minimatch": "2 || 3",
-                        "once": "^1.3.0",
-                        "path-is-absolute": "^1.0.0"
-                    }
-                }
-            }
-        },
         "component-bind": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
@@ -3840,17 +3581,6 @@
             "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
             "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
         },
-        "constantinople": {
-            "version": "3.1.2",
-            "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz",
-            "integrity": "sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==",
-            "requires": {
-                "@types/babel-types": "^7.0.0",
-                "@types/babylon": "^6.16.2",
-                "babel-types": "^6.26.0",
-                "babylon": "^6.18.0"
-            }
-        },
         "constants-browserify": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
@@ -4051,6 +3781,7 @@
             "version": "4.0.3",
             "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
             "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
+            "dev": true,
             "requires": {
                 "bn.js": "^4.1.0",
                 "elliptic": "^6.0.0"
@@ -4079,6 +3810,7 @@
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
             "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+            "dev": true,
             "requires": {
                 "cipher-base": "^1.0.1",
                 "inherits": "^2.0.1",
@@ -4091,6 +3823,7 @@
             "version": "1.1.7",
             "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
             "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+            "dev": true,
             "requires": {
                 "cipher-base": "^1.0.3",
                 "create-hash": "^1.1.0",
@@ -4109,11 +3842,6 @@
                 "gud": "^1.0.0"
             }
         },
-        "crelt": {
-            "version": "1.0.4",
-            "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.4.tgz",
-            "integrity": "sha512-l1cwMUOssGLEj5zgbut4lxJq95ZabOXVZnDybNqQRUtXh1lvUK7e7kJNm8SfvTQzYpE3AVJhIVUJKf382lMA7A=="
-        },
         "cross-env": {
             "version": "5.2.1",
             "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.1.tgz",
@@ -4183,6 +3911,7 @@
             "version": "3.12.0",
             "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
             "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+            "dev": true,
             "requires": {
                 "browserify-cipher": "^1.0.0",
                 "browserify-sign": "^4.0.0",
@@ -4313,6 +4042,7 @@
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
             "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+            "dev": true,
             "requires": {
                 "es5-ext": "^0.10.50",
                 "type": "^1.0.1"
@@ -4323,11 +4053,6 @@
             "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz",
             "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw=="
         },
-        "d3-format": {
-            "version": "1.4.4",
-            "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.4.tgz",
-            "integrity": "sha512-TWks25e7t8/cqctxCmxpUuzZN11QxIA7YrMbram94zMQ0PXjE4LVIMe/f6a4+xxL8HQ3OsAFULOINQi1pE62Aw=="
-        },
         "dashdash": {
             "version": "1.14.1",
             "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
@@ -4365,6 +4090,11 @@
                 }
             }
         },
+        "de-indent": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
+            "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0="
+        },
         "debounce": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz",
@@ -4529,11 +4259,6 @@
                 }
             }
         },
-        "defined": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
-            "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM="
-        },
         "del": {
             "version": "4.1.1",
             "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
@@ -4555,56 +4280,267 @@
                     "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
                     "dev": true,
                     "requires": {
-                        "array-union": "^1.0.1",
-                        "glob": "^7.0.3",
-                        "object-assign": "^4.0.1",
-                        "pify": "^2.0.0",
-                        "pinkie-promise": "^2.0.0"
-                    },
-                    "dependencies": {
-                        "pify": {
-                            "version": "2.3.0",
-                            "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-                            "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-                            "dev": true
-                        }
+                        "array-union": "^1.0.1",
+                        "glob": "^7.0.3",
+                        "object-assign": "^4.0.1",
+                        "pify": "^2.0.0",
+                        "pinkie-promise": "^2.0.0"
+                    },
+                    "dependencies": {
+                        "pify": {
+                            "version": "2.3.0",
+                            "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+                            "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+                            "dev": true
+                        }
+                    }
+                },
+                "rimraf": {
+                    "version": "2.7.1",
+                    "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+                    "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+                    "dev": true,
+                    "requires": {
+                        "glob": "^7.1.3"
+                    }
+                }
+            }
+        },
+        "delayed-stream": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+            "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+        },
+        "delegates": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+            "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
+        },
+        "denque": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
+            "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
+        },
+        "depcheck": {
+            "version": "0.9.2",
+            "resolved": "https://registry.npmjs.org/depcheck/-/depcheck-0.9.2.tgz",
+            "integrity": "sha512-w5f+lSZqLJJkk58s44eOd0Vor7hLZot4PlFL0y2JsIX5LuHQ2eAjHlDVeGBD4Mj6ZQSKakvKWRRCcPlvrdU2Sg==",
+            "requires": {
+                "@babel/parser": "^7.7.7",
+                "@babel/traverse": "^7.7.4",
+                "builtin-modules": "^3.0.0",
+                "camelcase": "^5.3.1",
+                "cosmiconfig": "^5.2.1",
+                "debug": "^4.1.1",
+                "deps-regex": "^0.1.4",
+                "js-yaml": "^3.4.2",
+                "lodash": "^4.17.15",
+                "minimatch": "^3.0.2",
+                "node-sass-tilde-importer": "^1.0.2",
+                "please-upgrade-node": "^3.2.0",
+                "require-package-name": "^2.0.1",
+                "resolve": "^1.14.1",
+                "vue-template-compiler": "^2.6.11",
+                "walkdir": "^0.4.1",
+                "yargs": "^15.0.2"
+            },
+            "dependencies": {
+                "ansi-regex": {
+                    "version": "5.0.0",
+                    "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+                    "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
+                },
+                "ansi-styles": {
+                    "version": "4.2.1",
+                    "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+                    "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+                    "requires": {
+                        "@types/color-name": "^1.1.1",
+                        "color-convert": "^2.0.1"
+                    }
+                },
+                "builtin-modules": {
+                    "version": "3.1.0",
+                    "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz",
+                    "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw=="
+                },
+                "cliui": {
+                    "version": "6.0.0",
+                    "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+                    "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+                    "requires": {
+                        "string-width": "^4.2.0",
+                        "strip-ansi": "^6.0.0",
+                        "wrap-ansi": "^6.2.0"
+                    }
+                },
+                "color-convert": {
+                    "version": "2.0.1",
+                    "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+                    "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+                    "requires": {
+                        "color-name": "~1.1.4"
+                    }
+                },
+                "color-name": {
+                    "version": "1.1.4",
+                    "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+                    "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+                },
+                "cosmiconfig": {
+                    "version": "5.2.1",
+                    "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+                    "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+                    "requires": {
+                        "import-fresh": "^2.0.0",
+                        "is-directory": "^0.3.1",
+                        "js-yaml": "^3.13.1",
+                        "parse-json": "^4.0.0"
+                    }
+                },
+                "debug": {
+                    "version": "4.1.1",
+                    "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+                    "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+                    "requires": {
+                        "ms": "^2.1.1"
+                    }
+                },
+                "emoji-regex": {
+                    "version": "8.0.0",
+                    "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+                    "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+                },
+                "find-up": {
+                    "version": "4.1.0",
+                    "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+                    "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+                    "requires": {
+                        "locate-path": "^5.0.0",
+                        "path-exists": "^4.0.0"
+                    }
+                },
+                "import-fresh": {
+                    "version": "2.0.0",
+                    "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+                    "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
+                    "requires": {
+                        "caller-path": "^2.0.0",
+                        "resolve-from": "^3.0.0"
+                    }
+                },
+                "is-fullwidth-code-point": {
+                    "version": "3.0.0",
+                    "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+                    "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
+                },
+                "locate-path": {
+                    "version": "5.0.0",
+                    "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+                    "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+                    "requires": {
+                        "p-locate": "^4.1.0"
+                    }
+                },
+                "p-locate": {
+                    "version": "4.1.0",
+                    "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+                    "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+                    "requires": {
+                        "p-limit": "^2.2.0"
+                    }
+                },
+                "parse-json": {
+                    "version": "4.0.0",
+                    "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+                    "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+                    "requires": {
+                        "error-ex": "^1.3.1",
+                        "json-parse-better-errors": "^1.0.1"
+                    }
+                },
+                "path-exists": {
+                    "version": "4.0.0",
+                    "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+                    "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
+                },
+                "resolve-from": {
+                    "version": "3.0.0",
+                    "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+                    "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
+                },
+                "string-width": {
+                    "version": "4.2.0",
+                    "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+                    "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+                    "requires": {
+                        "emoji-regex": "^8.0.0",
+                        "is-fullwidth-code-point": "^3.0.0",
+                        "strip-ansi": "^6.0.0"
+                    }
+                },
+                "strip-ansi": {
+                    "version": "6.0.0",
+                    "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+                    "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+                    "requires": {
+                        "ansi-regex": "^5.0.0"
                     }
                 },
-                "rimraf": {
-                    "version": "2.7.1",
-                    "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
-                    "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
-                    "dev": true,
+                "wrap-ansi": {
+                    "version": "6.2.0",
+                    "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+                    "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
                     "requires": {
-                        "glob": "^7.1.3"
+                        "ansi-styles": "^4.0.0",
+                        "string-width": "^4.1.0",
+                        "strip-ansi": "^6.0.0"
+                    }
+                },
+                "yargs": {
+                    "version": "15.3.1",
+                    "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
+                    "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
+                    "requires": {
+                        "cliui": "^6.0.0",
+                        "decamelize": "^1.2.0",
+                        "find-up": "^4.1.0",
+                        "get-caller-file": "^2.0.1",
+                        "require-directory": "^2.1.1",
+                        "require-main-filename": "^2.0.0",
+                        "set-blocking": "^2.0.0",
+                        "string-width": "^4.2.0",
+                        "which-module": "^2.0.0",
+                        "y18n": "^4.0.0",
+                        "yargs-parser": "^18.1.1"
+                    }
+                },
+                "yargs-parser": {
+                    "version": "18.1.3",
+                    "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+                    "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+                    "requires": {
+                        "camelcase": "^5.0.0",
+                        "decamelize": "^1.2.0"
                     }
                 }
             }
         },
-        "delayed-stream": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-            "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
-        },
-        "delegates": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
-            "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
-        },
-        "denque": {
-            "version": "1.4.1",
-            "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
-            "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
-        },
         "depd": {
             "version": "1.1.2",
             "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
             "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
         },
+        "deps-regex": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/deps-regex/-/deps-regex-0.1.4.tgz",
+            "integrity": "sha1-UYZnt2kUYKXn4KNBvnbrfOgJAYQ="
+        },
         "des.js": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
             "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+            "dev": true,
             "requires": {
                 "inherits": "^2.0.1",
                 "minimalistic-assert": "^1.0.0"
@@ -4632,29 +4568,16 @@
             "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
             "dev": true
         },
-        "detective": {
-            "version": "4.7.1",
-            "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz",
-            "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==",
-            "requires": {
-                "acorn": "^5.2.1",
-                "defined": "^1.0.0"
-            }
-        },
         "diff": {
             "version": "3.5.0",
             "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
             "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
         },
-        "diff-sequences": {
-            "version": "24.9.0",
-            "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz",
-            "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew=="
-        },
         "diffie-hellman": {
             "version": "5.0.3",
             "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
             "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+            "dev": true,
             "requires": {
                 "bn.js": "^4.1.0",
                 "miller-rabin": "^4.0.0",
@@ -4712,11 +4635,6 @@
                 "buffer-indexof": "^1.0.0"
             }
         },
-        "doctypes": {
-            "version": "1.1.0",
-            "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz",
-            "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk="
-        },
         "dom-helpers": {
             "version": "3.4.0",
             "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
@@ -4797,11 +4715,6 @@
             "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
             "dev": true
         },
-        "duplexer": {
-            "version": "0.1.1",
-            "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
-            "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E="
-        },
         "duplexer3": {
             "version": "0.1.4",
             "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
@@ -4867,15 +4780,11 @@
             "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
             "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
         },
-        "element-resize-event": {
-            "version": "2.0.9",
-            "resolved": "https://registry.npmjs.org/element-resize-event/-/element-resize-event-2.0.9.tgz",
-            "integrity": "sha1-L14VgaKW61J1IQwUG8VjQuIY+HY="
-        },
         "elliptic": {
             "version": "6.5.2",
             "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
             "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==",
+            "dev": true,
             "requires": {
                 "bn.js": "^4.4.0",
                 "brorand": "^1.0.1",
@@ -5023,15 +4932,6 @@
             "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
             "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
         },
-        "envify": {
-            "version": "3.4.1",
-            "resolved": "https://registry.npmjs.org/envify/-/envify-3.4.1.tgz",
-            "integrity": "sha1-1xIjKejfFoi6dxsSUBkXyc5cvOg=",
-            "requires": {
-                "jstransform": "^11.0.3",
-                "through": "~2.3.4"
-            }
-        },
         "errno": {
             "version": "0.1.7",
             "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
@@ -5081,6 +4981,7 @@
             "version": "0.10.53",
             "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
             "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+            "dev": true,
             "requires": {
                 "es6-iterator": "~2.0.3",
                 "es6-symbol": "~3.1.3",
@@ -5091,6 +4992,7 @@
             "version": "2.0.3",
             "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
             "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+            "dev": true,
             "requires": {
                 "d": "1",
                 "es5-ext": "^0.10.35",
@@ -5106,6 +5008,7 @@
             "version": "3.1.3",
             "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
             "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+            "dev": true,
             "requires": {
                 "d": "^1.0.1",
                 "ext": "^1.1.2"
@@ -5176,42 +5079,19 @@
         "esutils": {
             "version": "2.0.3",
             "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
-            "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
+            "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+            "dev": true
         },
         "etag": {
             "version": "1.8.1",
             "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
             "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
         },
-        "ev-emitter": {
-            "version": "1.1.1",
-            "resolved": "https://registry.npmjs.org/ev-emitter/-/ev-emitter-1.1.1.tgz",
-            "integrity": "sha512-ipiDYhdQSCZ4hSbX4rMW+XzNKMD1prg/sTvoVmSLkuQ1MVlwjJQQA+sW8tMYR3BLUr9KjodFV4pvzunvRhd33Q=="
-        },
-        "event-stream": {
-            "version": "3.3.5",
-            "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.5.tgz",
-            "integrity": "sha512-vyibDcu5JL20Me1fP734QBH/kenBGLZap2n0+XXM7mvuUPzJ20Ydqj1aKcIeMdri1p+PU+4yAKugjN8KCVst+g==",
-            "requires": {
-                "duplexer": "^0.1.1",
-                "from": "^0.1.7",
-                "map-stream": "0.0.7",
-                "pause-stream": "^0.0.11",
-                "split": "^1.0.1",
-                "stream-combiner": "^0.2.2",
-                "through": "^2.3.8"
-            }
-        },
         "event-target-shim": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
             "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
         },
-        "eventemitter3": {
-            "version": "2.0.3",
-            "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
-            "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo="
-        },
         "events": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz",
@@ -5231,6 +5111,7 @@
             "version": "1.0.3",
             "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
             "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+            "dev": true,
             "requires": {
                 "md5.js": "^1.3.4",
                 "safe-buffer": "^5.1.1"
@@ -5491,6 +5372,7 @@
             "version": "1.4.0",
             "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
             "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
+            "dev": true,
             "requires": {
                 "type": "^2.0.0"
             },
@@ -5498,7 +5380,8 @@
                 "type": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz",
-                    "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow=="
+                    "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==",
+                    "dev": true
                 }
             }
         },
@@ -5666,38 +5549,6 @@
                 "pend": "~1.2.0"
             }
         },
-        "feedparser": {
-            "version": "2.2.9",
-            "resolved": "https://registry.npmjs.org/feedparser/-/feedparser-2.2.9.tgz",
-            "integrity": "sha1-kTgZfa/a4F/K3eADa+6vYGbCxek=",
-            "requires": {
-                "addressparser": "^1.0.1",
-                "array-indexofobject": "~0.0.1",
-                "lodash.assign": "^4.2.0",
-                "lodash.get": "^4.4.2",
-                "lodash.has": "^4.5.2",
-                "lodash.uniq": "^4.5.0",
-                "mri": "^1.1.0",
-                "readable-stream": "^2.2.2",
-                "sax": "^1.2.4"
-            },
-            "dependencies": {
-                "readable-stream": {
-                    "version": "2.3.7",
-                    "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
-                    "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
-                    "requires": {
-                        "core-util-is": "~1.0.0",
-                        "inherits": "~2.0.3",
-                        "isarray": "~1.0.0",
-                        "process-nextick-args": "~2.0.0",
-                        "safe-buffer": "~5.1.1",
-                        "string_decoder": "~1.1.1",
-                        "util-deprecate": "~1.0.1"
-                    }
-                }
-            }
-        },
         "figgy-pudding": {
             "version": "3.5.2",
             "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
@@ -5727,11 +5578,6 @@
                 }
             }
         },
-        "file-type": {
-            "version": "7.7.1",
-            "resolved": "https://registry.npmjs.org/file-type/-/file-type-7.7.1.tgz",
-            "integrity": "sha512-bTrKkzzZI6wH+NXhyD3SOXtb2zXTw2SbwI2RxUlRcXVsnN7jNL5hJzVQLYv7FOQhxFkK4XWdAflEaWFpaLLWpQ=="
-        },
         "file-uri-to-path": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
@@ -5830,6 +5676,11 @@
                 "q": "^1.0.1"
             }
         },
+        "find-parent-dir": {
+            "version": "0.3.0",
+            "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz",
+            "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ="
+        },
         "find-root": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
@@ -5899,6 +5750,7 @@
             "version": "1.5.10",
             "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
             "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+            "dev": true,
             "requires": {
                 "debug": "=3.1.0"
             },
@@ -5907,6 +5759,7 @@
                     "version": "3.1.0",
                     "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
                     "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+                    "dev": true,
                     "requires": {
                         "ms": "2.0.0"
                     }
@@ -5914,15 +5767,11 @@
                 "ms": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+                    "dev": true
                 }
             }
         },
-        "font-awesome": {
-            "version": "4.7.0",
-            "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
-            "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM="
-        },
         "for-each-property": {
             "version": "0.0.4",
             "resolved": "https://registry.npmjs.org/for-each-property/-/for-each-property-0.0.4.tgz",
@@ -5969,6 +5818,7 @@
             "version": "2.5.1",
             "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
             "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
+            "dev": true,
             "requires": {
                 "asynckit": "^0.4.0",
                 "combined-stream": "^1.0.6",
@@ -5998,11 +5848,6 @@
             "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
             "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
         },
-        "from": {
-            "version": "0.1.7",
-            "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
-            "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4="
-        },
         "from2": {
             "version": "2.3.0",
             "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
@@ -6337,6 +6182,11 @@
                 "which": "^1.2.14"
             }
         },
+        "globals": {
+            "version": "11.12.0",
+            "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+            "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
+        },
         "globby": {
             "version": "7.1.1",
             "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz",
@@ -6617,6 +6467,7 @@
             "version": "3.0.4",
             "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
             "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+            "dev": true,
             "requires": {
                 "inherits": "^2.0.1",
                 "safe-buffer": "^5.0.1"
@@ -6626,6 +6477,7 @@
             "version": "1.1.7",
             "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
             "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+            "dev": true,
             "requires": {
                 "inherits": "^2.0.3",
                 "minimalistic-assert": "^1.0.1"
@@ -6640,6 +6492,7 @@
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
             "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+            "dev": true,
             "requires": {
                 "hash.js": "^1.0.3",
                 "minimalistic-assert": "^1.0.0",
@@ -6848,85 +6701,6 @@
             "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz",
             "integrity": "sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0="
         },
-        "ibm-cloud-sdk-core": {
-            "version": "2.3.0",
-            "resolved": "https://registry.npmjs.org/ibm-cloud-sdk-core/-/ibm-cloud-sdk-core-2.3.0.tgz",
-            "integrity": "sha512-s8qDwqHSp841q88Jo96nMlYwLcBPc/EakXFS27hCwbrG1ntZCb2QE7RJVKF26FxuCFmktbNwHIGg7ehiZZ+TUw==",
-            "requires": {
-                "@types/extend": "~3.0.0",
-                "@types/file-type": "~5.2.1",
-                "@types/isstream": "^0.1.0",
-                "@types/jest": "^24.0.23",
-                "@types/node": "~10.14.19",
-                "axios": "^0.18.0",
-                "axios-cookiejar-support": "^0.5.1",
-                "camelcase": "^5.3.1",
-                "debug": "^4.1.1",
-                "dotenv": "^6.2.0",
-                "extend": "~3.0.2",
-                "file-type": "^7.7.1",
-                "form-data": "^2.3.3",
-                "isstream": "~0.1.2",
-                "jsonwebtoken": "^8.5.1",
-                "lodash.isempty": "^4.4.0",
-                "mime-types": "~2.1.18",
-                "object.omit": "~3.0.0",
-                "object.pick": "~1.3.0",
-                "semver": "^6.2.0",
-                "ts-jest": "^24.2.0"
-            },
-            "dependencies": {
-                "@types/node": {
-                    "version": "10.14.22",
-                    "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.22.tgz",
-                    "integrity": "sha512-9taxKC944BqoTVjE+UT3pQH0nHZlTvITwfsOZqyc+R3sfJuxaTtxWjfn1K2UlxyPcKHf0rnaXcVFrS9F9vf0bw=="
-                },
-                "debug": {
-                    "version": "4.1.1",
-                    "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
-                    "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
-                    "requires": {
-                        "ms": "^2.1.1"
-                    }
-                },
-                "dotenv": {
-                    "version": "6.2.0",
-                    "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz",
-                    "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w=="
-                },
-                "semver": {
-                    "version": "6.3.0",
-                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-                    "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
-                }
-            }
-        },
-        "ibm-watson": {
-            "version": "5.5.0",
-            "resolved": "https://registry.npmjs.org/ibm-watson/-/ibm-watson-5.5.0.tgz",
-            "integrity": "sha512-gcijKSFTOMLcjEnSpeUa4/31naeMSZsz8t/wYNrR5c8gp1VN9LbJ3vhn3nFislfLYopTkNnWzya7w8oMhW4SGg==",
-            "requires": {
-                "@types/async": "^2.4.2",
-                "@types/extend": "^3.0.1",
-                "@types/isstream": "^0.1.0",
-                "@types/node": "^11.9.4",
-                "@types/websocket": "^1.0.0",
-                "async": "^2.6.2",
-                "axios": "^0.18.0",
-                "camelcase": "^5.3.1",
-                "extend": "~3.0.2",
-                "ibm-cloud-sdk-core": "^2.0.3",
-                "isstream": "~0.1.2",
-                "websocket": "^1.0.28"
-            },
-            "dependencies": {
-                "@types/node": {
-                    "version": "11.15.12",
-                    "resolved": "https://registry.npmjs.org/@types/node/-/node-11.15.12.tgz",
-                    "integrity": "sha512-iefeBfpmhoYaZfj+gJM5z9H9eiTwhuzhPsJgH/flx4HP2SBI2FNDra1D3vKljqPLGDr9Cazvh9gP9Xszc30ncA=="
-                }
-            }
-        },
         "iconv-lite": {
             "version": "0.4.24",
             "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -7033,19 +6807,6 @@
                 }
             }
         },
-        "imagesloaded": {
-            "version": "4.1.4",
-            "resolved": "https://registry.npmjs.org/imagesloaded/-/imagesloaded-4.1.4.tgz",
-            "integrity": "sha512-ltiBVcYpc/TYTF5nolkMNsnREHW+ICvfQ3Yla2Sgr71YFwQ86bDwV9hgpFhFtrGPuwEx5+LqOHIrdXBdoWwwsA==",
-            "requires": {
-                "ev-emitter": "^1.0.0"
-            }
-        },
-        "immutable": {
-            "version": "4.0.0-rc.12",
-            "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.12.tgz",
-            "integrity": "sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A=="
-        },
         "import-fresh": {
             "version": "3.2.1",
             "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
@@ -7279,19 +7040,6 @@
             "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
             "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw=="
         },
-        "invariant": {
-            "version": "2.2.4",
-            "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
-            "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
-            "requires": {
-                "loose-envify": "^1.0.0"
-            }
-        },
-        "invert-kv": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
-            "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
-        },
         "ip": {
             "version": "1.1.5",
             "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
@@ -7301,7 +7049,8 @@
         "ip-regex": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
-            "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk="
+            "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
+            "dev": true
         },
         "ipaddr.js": {
             "version": "1.9.1",
@@ -7419,21 +7168,10 @@
                 }
             }
         },
-        "is-expression": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz",
-            "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=",
-            "requires": {
-                "acorn": "~4.0.2",
-                "object-assign": "^4.0.1"
-            },
-            "dependencies": {
-                "acorn": {
-                    "version": "4.0.13",
-                    "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
-                    "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
-                }
-            }
+        "is-directory": {
+            "version": "0.3.1",
+            "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+            "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE="
         },
         "is-extendable": {
             "version": "1.0.1",
@@ -7550,11 +7288,6 @@
                 "isobject": "^3.0.1"
             }
         },
-        "is-promise": {
-            "version": "2.2.2",
-            "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
-            "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
-        },
         "is-redirect": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
@@ -7645,34 +7378,10 @@
                 "lodash.get": "^4.4.2"
             }
         },
-        "jest-diff": {
-            "version": "24.9.0",
-            "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz",
-            "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==",
-            "requires": {
-                "chalk": "^2.0.1",
-                "diff-sequences": "^24.9.0",
-                "jest-get-type": "^24.9.0",
-                "pretty-format": "^24.9.0"
-            }
-        },
-        "jest-get-type": {
-            "version": "24.9.0",
-            "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz",
-            "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q=="
-        },
         "jquery": {
-            "version": "3.5.0",
-            "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz",
-            "integrity": "sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ=="
-        },
-        "jquery-awesome-cursor": {
-            "version": "0.3.1",
-            "resolved": "https://registry.npmjs.org/jquery-awesome-cursor/-/jquery-awesome-cursor-0.3.1.tgz",
-            "integrity": "sha1-1pcaMrRiRhC868rAkDsAFWHQXso=",
-            "requires": {
-                "font-awesome": "4.x"
-            }
+            "version": "3.5.1",
+            "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz",
+            "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg=="
         },
         "js-base64": {
             "version": "2.5.2",
@@ -7684,11 +7393,6 @@
             "resolved": "https://registry.npmjs.org/js-datepicker/-/js-datepicker-4.6.6.tgz",
             "integrity": "sha512-kLsE2oHfQM6pzdWNA7Y8HwCHaZIVURItPds7YVJnbe1z1OmQFzN7lfg6yFbDDWOyNjdHZGzWDy3jSDN2W0pNZQ=="
         },
-        "js-stringify": {
-            "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
-            "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds="
-        },
         "js-tokens": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -7785,6 +7489,11 @@
                 }
             }
         },
+        "jsesc": {
+            "version": "2.5.2",
+            "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+            "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
+        },
         "json-bigint": {
             "version": "0.3.0",
             "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz",
@@ -7808,11 +7517,6 @@
             "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
             "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
         },
-        "json-stringify-pretty-compact": {
-            "version": "1.2.0",
-            "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-1.2.0.tgz",
-            "integrity": "sha512-/11Pj1OyX814QMKO7K8l85SHPTr/KsFxHp8GE2zVa0BtJgGimDjXHfM3FhC7keQdWDea7+nXf+f1de7ATZcZkQ=="
-        },
         "json-stringify-safe": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
@@ -7824,14 +7528,6 @@
             "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==",
             "dev": true
         },
-        "json5": {
-            "version": "2.1.3",
-            "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
-            "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
-            "requires": {
-                "minimist": "^1.2.5"
-            }
-        },
         "jsonfile": {
             "version": "2.4.0",
             "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
@@ -7843,113 +7539,17 @@
         "jsonschema": {
             "version": "1.2.6",
             "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.6.tgz",
-            "integrity": "sha512-SqhURKZG07JyKKeo/ir24QnS4/BV7a6gQy93bUSe4lUdNp0QNpIz2c9elWJQ9dpc5cQYY6cvCzgRwy0MQCLyqA=="
-        },
-        "jsonwebtoken": {
-            "version": "8.5.1",
-            "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
-            "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
-            "requires": {
-                "jws": "^3.2.2",
-                "lodash.includes": "^4.3.0",
-                "lodash.isboolean": "^3.0.3",
-                "lodash.isinteger": "^4.0.4",
-                "lodash.isnumber": "^3.0.3",
-                "lodash.isplainobject": "^4.0.6",
-                "lodash.isstring": "^4.0.1",
-                "lodash.once": "^4.0.0",
-                "ms": "^2.1.1",
-                "semver": "^5.6.0"
-            }
-        },
-        "jsprim": {
-            "version": "1.4.1",
-            "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-            "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
-            "requires": {
-                "assert-plus": "1.0.0",
-                "extsprintf": "1.3.0",
-                "json-schema": "0.2.3",
-                "verror": "1.10.0"
-            }
-        },
-        "jstransform": {
-            "version": "11.0.3",
-            "resolved": "https://registry.npmjs.org/jstransform/-/jstransform-11.0.3.tgz",
-            "integrity": "sha1-CaeJk+CuTU70SH9hVakfYZDLQiM=",
-            "requires": {
-                "base62": "^1.1.0",
-                "commoner": "^0.10.1",
-                "esprima-fb": "^15001.1.0-dev-harmony-fb",
-                "object-assign": "^2.0.0",
-                "source-map": "^0.4.2"
-            },
-            "dependencies": {
-                "esprima-fb": {
-                    "version": "15001.1.0-dev-harmony-fb",
-                    "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1.0-dev-harmony-fb.tgz",
-                    "integrity": "sha1-MKlHMDxrjV6VW+4rmbHSMyBqaQE="
-                },
-                "object-assign": {
-                    "version": "2.1.1",
-                    "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz",
-                    "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo="
-                },
-                "source-map": {
-                    "version": "0.4.4",
-                    "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
-                    "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
-                    "requires": {
-                        "amdefine": ">=0.0.4"
-                    }
-                }
-            }
-        },
-        "jstransformer": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
-            "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=",
-            "requires": {
-                "is-promise": "^2.0.0",
-                "promise": "^7.0.1"
-            }
-        },
-        "jsx-to-string": {
-            "version": "1.4.0",
-            "resolved": "https://registry.npmjs.org/jsx-to-string/-/jsx-to-string-1.4.0.tgz",
-            "integrity": "sha1-Ztw013PaufQP6ZPP+ZQOXaZVtwU=",
-            "requires": {
-                "immutable": "^4.0.0-rc.9",
-                "json-stringify-pretty-compact": "^1.0.1",
-                "react": "^0.14.0"
-            },
-            "dependencies": {
-                "fbjs": {
-                    "version": "0.6.1",
-                    "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.6.1.tgz",
-                    "integrity": "sha1-lja3cF9bqWhNRLcveDISVK/IYPc=",
-                    "requires": {
-                        "core-js": "^1.0.0",
-                        "loose-envify": "^1.0.0",
-                        "promise": "^7.0.3",
-                        "ua-parser-js": "^0.7.9",
-                        "whatwg-fetch": "^0.9.0"
-                    }
-                },
-                "react": {
-                    "version": "0.14.9",
-                    "resolved": "https://registry.npmjs.org/react/-/react-0.14.9.tgz",
-                    "integrity": "sha1-kRCmSXxJ1EuhwO3TF67CnC4NkdE=",
-                    "requires": {
-                        "envify": "^3.0.0",
-                        "fbjs": "^0.6.1"
-                    }
-                },
-                "whatwg-fetch": {
-                    "version": "0.9.0",
-                    "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-0.9.0.tgz",
-                    "integrity": "sha1-DjaExsuZlbQ+/J3wPkw2XZX9nMA="
-                }
+            "integrity": "sha512-SqhURKZG07JyKKeo/ir24QnS4/BV7a6gQy93bUSe4lUdNp0QNpIz2c9elWJQ9dpc5cQYY6cvCzgRwy0MQCLyqA=="
+        },
+        "jsprim": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+            "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+            "requires": {
+                "assert-plus": "1.0.0",
+                "extsprintf": "1.3.0",
+                "json-schema": "0.2.3",
+                "verror": "1.10.0"
             }
         },
         "jwa": {
@@ -8011,11 +7611,6 @@
                 "package-json": "^4.0.0"
             }
         },
-        "lazy-cache": {
-            "version": "1.0.4",
-            "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
-            "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4="
-        },
         "lazystream": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
@@ -8040,14 +7635,6 @@
                 }
             }
         },
-        "lcid": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
-            "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
-            "requires": {
-                "invert-kv": "^1.0.0"
-            }
-        },
         "levn": {
             "version": "0.3.0",
             "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
@@ -8167,16 +7754,6 @@
             "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
             "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
         },
-        "lodash-es": {
-            "version": "4.17.15",
-            "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz",
-            "integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ=="
-        },
-        "lodash.assign": {
-            "version": "4.2.0",
-            "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
-            "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc="
-        },
         "lodash.chunk": {
             "version": "4.2.0",
             "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz",
@@ -8202,61 +7779,16 @@
             "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
             "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
         },
-        "lodash.has": {
-            "version": "4.5.2",
-            "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz",
-            "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI="
-        },
-        "lodash.includes": {
-            "version": "4.3.0",
-            "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
-            "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
-        },
-        "lodash.isboolean": {
-            "version": "3.0.3",
-            "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
-            "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
-        },
-        "lodash.isempty": {
-            "version": "4.4.0",
-            "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz",
-            "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4="
-        },
-        "lodash.isequal": {
-            "version": "4.5.0",
-            "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
-            "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
-        },
-        "lodash.isinteger": {
-            "version": "4.0.4",
-            "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
-            "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
-        },
-        "lodash.isnumber": {
-            "version": "3.0.3",
-            "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
-            "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
-        },
         "lodash.isplainobject": {
             "version": "4.0.6",
             "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
             "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
         },
-        "lodash.isstring": {
-            "version": "4.0.1",
-            "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
-            "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
-        },
         "lodash.memoize": {
             "version": "4.1.2",
             "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
             "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
         },
-        "lodash.once": {
-            "version": "4.1.1",
-            "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
-            "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
-        },
         "lodash.padend": {
             "version": "4.6.1",
             "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
@@ -8273,11 +7805,6 @@
             "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
             "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg="
         },
-        "lodash.uniq": {
-            "version": "4.5.0",
-            "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
-            "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M="
-        },
         "log-symbols": {
             "version": "2.2.0",
             "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
@@ -8302,11 +7829,6 @@
                 "object.assign": "^4.1.0"
             }
         },
-        "longest": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
-            "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
-        },
         "loose-envify": {
             "version": "1.4.0",
             "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -8406,7 +7928,8 @@
         "make-error": {
             "version": "1.3.6",
             "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
-            "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
+            "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+            "dev": true
         },
         "map-age-cleaner": {
             "version": "0.1.3",
@@ -8427,11 +7950,6 @@
             "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
             "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0="
         },
-        "map-stream": {
-            "version": "0.0.7",
-            "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
-            "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg="
-        },
         "map-visit": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
@@ -8449,6 +7967,7 @@
             "version": "1.3.5",
             "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
             "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+            "dev": true,
             "requires": {
                 "hash-base": "^3.0.0",
                 "inherits": "^2.0.1",
@@ -8561,6 +8080,7 @@
             "version": "4.0.1",
             "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
             "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+            "dev": true,
             "requires": {
                 "bn.js": "^4.0.0",
                 "brorand": "^1.0.1"
@@ -8598,12 +8118,14 @@
         "minimalistic-assert": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
-            "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
+            "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+            "dev": true
         },
         "minimalistic-crypto-utils": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
-            "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
+            "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+            "dev": true
         },
         "minimatch": {
             "version": "3.0.4",
@@ -8951,11 +8473,6 @@
                 }
             }
         },
-        "mri": {
-            "version": "1.1.5",
-            "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.5.tgz",
-            "integrity": "sha512-d2RKzMD4JNyHMbnbWnznPaa8vbdlq/4pNZ3IgdaGrVbBhebBsGUUE/6qorTMYNS6TwuH3ilfOlD2bf4Igh8CKg=="
-        },
         "ms": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
@@ -9005,11 +8522,6 @@
             "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
             "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
         },
-        "native-promise-only": {
-            "version": "0.8.1",
-            "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz",
-            "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE="
-        },
         "needle": {
             "version": "2.4.1",
             "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.1.tgz",
@@ -9208,37 +8720,10 @@
                 "which": "^1.3.0"
             }
         },
-        "node-pre-gyp": {
-            "version": "0.14.0",
-            "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz",
-            "integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==",
-            "requires": {
-                "detect-libc": "^1.0.2",
-                "mkdirp": "^0.5.1",
-                "needle": "^2.2.1",
-                "nopt": "^4.0.1",
-                "npm-packlist": "^1.1.6",
-                "npmlog": "^4.0.2",
-                "rc": "^1.2.7",
-                "rimraf": "^2.6.1",
-                "semver": "^5.3.0",
-                "tar": "^4.4.2"
-            },
-            "dependencies": {
-                "rimraf": {
-                    "version": "2.7.1",
-                    "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
-                    "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
-                    "requires": {
-                        "glob": "^7.1.3"
-                    }
-                }
-            }
-        },
         "node-sass": {
-            "version": "4.14.0",
-            "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.0.tgz",
-            "integrity": "sha512-AxqU+DFpk0lEz95sI6jO0hU0Rwyw7BXVEv6o9OItoXLyeygPeaSpiV4rwQb10JiTghHaa0gZeD21sz+OsQluaw==",
+            "version": "4.14.1",
+            "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz",
+            "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==",
             "requires": {
                 "async-foreach": "^0.1.3",
                 "chalk": "^1.1.1",
@@ -9254,7 +8739,7 @@
                 "node-gyp": "^3.8.0",
                 "npmlog": "^4.0.0",
                 "request": "^2.88.0",
-                "sass-graph": "^2.2.4",
+                "sass-graph": "2.2.5",
                 "stdout-stream": "^1.4.0",
                 "true-case-path": "^1.0.2"
             },
@@ -9301,44 +8786,19 @@
                 }
             }
         },
+        "node-sass-tilde-importer": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/node-sass-tilde-importer/-/node-sass-tilde-importer-1.0.2.tgz",
+            "integrity": "sha512-Swcmr38Y7uB78itQeBm3mThjxBy9/Ah/ykPIaURY/L6Nec9AyRoL/jJ7ECfMR+oZeCTVQNxVMu/aHU+TLRVbdg==",
+            "requires": {
+                "find-parent-dir": "^0.3.0"
+            }
+        },
         "node-stream-zip": {
             "version": "1.9.2",
             "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.9.2.tgz",
             "integrity": "sha512-X9gnhFH8Egchv+CJwtiGYFtiRotf/gDL+MB3pV7KGFNbeYDo0NqAYocdQEU2czXj6npta9SbPj4bow1yQtoffA=="
         },
-        "node-tesseract": {
-            "version": "0.2.7",
-            "resolved": "https://registry.npmjs.org/node-tesseract/-/node-tesseract-0.2.7.tgz",
-            "integrity": "sha1-yPAvuDUaQnByc1d4wFGYI/JgG4Q=",
-            "requires": {
-                "glob": "^5.0.10",
-                "node-uuid": "^1.4.1"
-            },
-            "dependencies": {
-                "glob": {
-                    "version": "5.0.15",
-                    "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
-                    "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
-                    "requires": {
-                        "inflight": "^1.0.4",
-                        "inherits": "2",
-                        "minimatch": "2 || 3",
-                        "once": "^1.3.0",
-                        "path-is-absolute": "^1.0.0"
-                    }
-                },
-                "node-uuid": {
-                    "version": "1.4.8",
-                    "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
-                    "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc="
-                }
-            }
-        },
-        "node-tesseract-ocr": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/node-tesseract-ocr/-/node-tesseract-ocr-1.0.0.tgz",
-            "integrity": "sha512-1u6KNqrt0jGK8Fdrm8JfQD4bctEScpnDtsEV42dmZ54zQRov+OUZZb4a7uy4V+OKENn7fKpgB5WIza5ernGHzA=="
-        },
         "nodemailer": {
             "version": "5.1.1",
             "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-5.1.1.tgz",
@@ -13134,14 +12594,6 @@
                 "es-abstract": "^1.17.0-next.1"
             }
         },
-        "object.omit": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-3.0.0.tgz",
-            "integrity": "sha512-EO+BCv6LJfu+gBIF3ggLicFebFLN5zqzz/WWJlMFfkMyGth+oBkhxzDl0wx2W4GkLzuQs/FsSkXZb2IMWQqmBQ==",
-            "requires": {
-                "is-extendable": "^1.0.0"
-            }
-        },
         "object.pick": {
             "version": "1.3.0",
             "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
@@ -13225,14 +12677,6 @@
             "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
             "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
         },
-        "os-locale": {
-            "version": "1.4.0",
-            "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
-            "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
-            "requires": {
-                "lcid": "^1.0.0"
-            }
-        },
         "os-tmpdir": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
@@ -13357,6 +12801,7 @@
             "version": "5.1.5",
             "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz",
             "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==",
+            "dev": true,
             "requires": {
                 "asn1.js": "^4.0.0",
                 "browserify-aes": "^1.0.0",
@@ -13515,18 +12960,11 @@
             "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
             "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
         },
-        "pause-stream": {
-            "version": "0.0.11",
-            "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
-            "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
-            "requires": {
-                "through": "~2.3"
-            }
-        },
         "pbkdf2": {
             "version": "3.0.17",
             "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
             "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
+            "dev": true,
             "requires": {
                 "create-hash": "^1.1.2",
                 "create-hmac": "^1.1.4",
@@ -13566,7 +13004,8 @@
         "pify": {
             "version": "4.0.1",
             "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
-            "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
+            "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+            "dev": true
         },
         "pinkie": {
             "version": "2.0.4",
@@ -13640,6 +13079,14 @@
                 }
             }
         },
+        "please-upgrade-node": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
+            "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
+            "requires": {
+                "semver-compare": "^1.0.0"
+            }
+        },
         "pn": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
@@ -13780,29 +13227,6 @@
             "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
             "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
         },
-        "pretty-format": {
-            "version": "24.9.0",
-            "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz",
-            "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==",
-            "requires": {
-                "@jest/types": "^24.9.0",
-                "ansi-regex": "^4.0.0",
-                "ansi-styles": "^3.2.0",
-                "react-is": "^16.8.4"
-            },
-            "dependencies": {
-                "ansi-regex": {
-                    "version": "4.1.0",
-                    "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
-                    "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
-                }
-            }
-        },
-        "private": {
-            "version": "0.1.8",
-            "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
-            "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg=="
-        },
         "probe-image-size": {
             "version": "4.1.1",
             "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-4.1.1.tgz",
@@ -13863,25 +13287,6 @@
                 "react-is": "^16.8.1"
             }
         },
-        "prop-types-extra": {
-            "version": "1.1.1",
-            "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz",
-            "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==",
-            "requires": {
-                "react-is": "^16.3.2",
-                "warning": "^4.0.0"
-            },
-            "dependencies": {
-                "warning": {
-                    "version": "4.0.3",
-                    "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
-                    "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
-                    "requires": {
-                        "loose-envify": "^1.0.0"
-                    }
-                }
-            }
-        },
         "prosemirror-commands": {
             "version": "1.1.4",
             "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.1.4.tgz",
@@ -13892,48 +13297,11 @@
                 "prosemirror-transform": "^1.0.0"
             }
         },
-        "prosemirror-dropcursor": {
-            "version": "1.3.2",
-            "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.3.2.tgz",
-            "integrity": "sha512-4c94OUGyobGnwcQI70OXyMhE/9T4aTgjU+CHxkd5c7D+jH/J0mKM/lk+jneFVKt7+E4/M0D9HzRPifu8U28Thw==",
-            "requires": {
-                "prosemirror-state": "^1.0.0",
-                "prosemirror-transform": "^1.1.0",
-                "prosemirror-view": "^1.1.0"
-            }
-        },
-        "prosemirror-example-setup": {
-            "version": "1.1.2",
-            "resolved": "https://registry.npmjs.org/prosemirror-example-setup/-/prosemirror-example-setup-1.1.2.tgz",
-            "integrity": "sha512-MTpIMyqk08jFnzxeRMCinCEMtVSTUtxKgQBGxfCbVe9C6zIOqp9qZZJz5Ojaad1GETySyuj8+OIHHvQsIaaaGQ==",
-            "requires": {
-                "prosemirror-commands": "^1.0.0",
-                "prosemirror-dropcursor": "^1.0.0",
-                "prosemirror-gapcursor": "^1.0.0",
-                "prosemirror-history": "^1.0.0",
-                "prosemirror-inputrules": "^1.0.0",
-                "prosemirror-keymap": "^1.0.0",
-                "prosemirror-menu": "^1.0.0",
-                "prosemirror-schema-list": "^1.0.0",
-                "prosemirror-state": "^1.0.0"
-            }
-        },
         "prosemirror-find-replace": {
             "version": "0.9.0",
             "resolved": "https://registry.npmjs.org/prosemirror-find-replace/-/prosemirror-find-replace-0.9.0.tgz",
             "integrity": "sha1-QgsENNF5xdBJD44hSNhVGpVJY4I="
         },
-        "prosemirror-gapcursor": {
-            "version": "1.1.5",
-            "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.1.5.tgz",
-            "integrity": "sha512-SjbUZq5pgsBDuV3hu8GqgIpZR5eZvGLM+gPQTqjVVYSMUCfKW3EGXTEYaLHEl1bGduwqNC95O3bZflgtAb4L6w==",
-            "requires": {
-                "prosemirror-keymap": "^1.0.0",
-                "prosemirror-model": "^1.0.0",
-                "prosemirror-state": "^1.0.0",
-                "prosemirror-view": "^1.0.0"
-            }
-        },
         "prosemirror-history": {
             "version": "1.1.3",
             "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.1.3.tgz",
@@ -13962,17 +13330,6 @@
                 "w3c-keyname": "^2.2.0"
             }
         },
-        "prosemirror-menu": {
-            "version": "1.1.4",
-            "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.1.4.tgz",
-            "integrity": "sha512-2ROsji/X9ciDnVSRvSTqFygI34GEdHfQSsK4zBKjPxSEroeiHHcdRMS1ofNIf2zM0Vpp5/YqfpxynElymQkqzg==",
-            "requires": {
-                "crelt": "^1.0.0",
-                "prosemirror-commands": "^1.0.0",
-                "prosemirror-history": "^1.0.0",
-                "prosemirror-state": "^1.0.0"
-            }
-        },
         "prosemirror-model": {
             "version": "1.9.1",
             "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.9.1.tgz",
@@ -13981,14 +13338,6 @@
                 "orderedmap": "^1.1.0"
             }
         },
-        "prosemirror-schema-basic": {
-            "version": "1.1.2",
-            "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.1.2.tgz",
-            "integrity": "sha512-G4q8WflNsR1Q33QAV4MQO0xWrHLOJ+BQcKswGXMy626wlQj6c/1n1v4eC9ns+h2y1r/fJHZEgSZnsNhm9lbrDw==",
-            "requires": {
-                "prosemirror-model": "^1.2.0"
-            }
-        },
         "prosemirror-schema-list": {
             "version": "1.1.2",
             "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.1.2.tgz",
@@ -14064,6 +13413,7 @@
             "version": "4.0.3",
             "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
             "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+            "dev": true,
             "requires": {
                 "bn.js": "^4.1.0",
                 "browserify-rsa": "^4.0.0",
@@ -14073,120 +13423,6 @@
                 "safe-buffer": "^5.1.2"
             }
         },
-        "pug": {
-            "version": "2.0.4",
-            "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.4.tgz",
-            "integrity": "sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw==",
-            "requires": {
-                "pug-code-gen": "^2.0.2",
-                "pug-filters": "^3.1.1",
-                "pug-lexer": "^4.1.0",
-                "pug-linker": "^3.0.6",
-                "pug-load": "^2.0.12",
-                "pug-parser": "^5.0.1",
-                "pug-runtime": "^2.0.5",
-                "pug-strip-comments": "^1.0.4"
-            }
-        },
-        "pug-attrs": {
-            "version": "2.0.4",
-            "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.4.tgz",
-            "integrity": "sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ==",
-            "requires": {
-                "constantinople": "^3.0.1",
-                "js-stringify": "^1.0.1",
-                "pug-runtime": "^2.0.5"
-            }
-        },
-        "pug-code-gen": {
-            "version": "2.0.2",
-            "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.2.tgz",
-            "integrity": "sha512-kROFWv/AHx/9CRgoGJeRSm+4mLWchbgpRzTEn8XCiwwOy6Vh0gAClS8Vh5TEJ9DBjaP8wCjS3J6HKsEsYdvaCw==",
-            "requires": {
-                "constantinople": "^3.1.2",
-                "doctypes": "^1.1.0",
-                "js-stringify": "^1.0.1",
-                "pug-attrs": "^2.0.4",
-                "pug-error": "^1.3.3",
-                "pug-runtime": "^2.0.5",
-                "void-elements": "^2.0.1",
-                "with": "^5.0.0"
-            }
-        },
-        "pug-error": {
-            "version": "1.3.3",
-            "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.3.tgz",
-            "integrity": "sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ=="
-        },
-        "pug-filters": {
-            "version": "3.1.1",
-            "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.1.tgz",
-            "integrity": "sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg==",
-            "requires": {
-                "clean-css": "^4.1.11",
-                "constantinople": "^3.0.1",
-                "jstransformer": "1.0.0",
-                "pug-error": "^1.3.3",
-                "pug-walk": "^1.1.8",
-                "resolve": "^1.1.6",
-                "uglify-js": "^2.6.1"
-            }
-        },
-        "pug-lexer": {
-            "version": "4.1.0",
-            "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-4.1.0.tgz",
-            "integrity": "sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA==",
-            "requires": {
-                "character-parser": "^2.1.1",
-                "is-expression": "^3.0.0",
-                "pug-error": "^1.3.3"
-            }
-        },
-        "pug-linker": {
-            "version": "3.0.6",
-            "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.6.tgz",
-            "integrity": "sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg==",
-            "requires": {
-                "pug-error": "^1.3.3",
-                "pug-walk": "^1.1.8"
-            }
-        },
-        "pug-load": {
-            "version": "2.0.12",
-            "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.12.tgz",
-            "integrity": "sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==",
-            "requires": {
-                "object-assign": "^4.1.0",
-                "pug-walk": "^1.1.8"
-            }
-        },
-        "pug-parser": {
-            "version": "5.0.1",
-            "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.1.tgz",
-            "integrity": "sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA==",
-            "requires": {
-                "pug-error": "^1.3.3",
-                "token-stream": "0.0.1"
-            }
-        },
-        "pug-runtime": {
-            "version": "2.0.5",
-            "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.5.tgz",
-            "integrity": "sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw=="
-        },
-        "pug-strip-comments": {
-            "version": "1.0.4",
-            "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz",
-            "integrity": "sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==",
-            "requires": {
-                "pug-error": "^1.3.3"
-            }
-        },
-        "pug-walk": {
-            "version": "1.1.8",
-            "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.8.tgz",
-            "integrity": "sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA=="
-        },
         "pump": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -14317,6 +13553,7 @@
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
             "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+            "dev": true,
             "requires": {
                 "safe-buffer": "^5.1.0"
             }
@@ -14325,6 +13562,7 @@
             "version": "1.0.4",
             "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
             "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+            "dev": true,
             "requires": {
                 "randombytes": "^2.0.5",
                 "safe-buffer": "^5.1.0"
@@ -14398,15 +13636,6 @@
                 "prop-types": "^15.6.2"
             }
         },
-        "react-anime": {
-            "version": "2.3.2",
-            "resolved": "https://registry.npmjs.org/react-anime/-/react-anime-2.3.2.tgz",
-            "integrity": "sha512-Wh9p1EdU5NTc2lyemHlaGG0QKuUYhpeGbh1Auw14Be+vukIkbCIaBMOyFya0Q7SIjSPzTNNpIgnD3oIv8TXWiw==",
-            "requires": {
-                "animejs": "^3.1.0",
-                "lodash.isequal": "^4.5.0"
-            }
-        },
         "react-autosuggest": {
             "version": "9.4.3",
             "resolved": "https://registry.npmjs.org/react-autosuggest/-/react-autosuggest-9.4.3.tgz",
@@ -14427,61 +13656,6 @@
                 "section-iterator": "^2.0.0"
             }
         },
-        "react-bootstrap": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.0.1.tgz",
-            "integrity": "sha512-xMHwsvDN7sIv26P9wWiosWjITZije2dRCjEJHVfV2KFoSJY+8uv2zttEw0XMB7xviQcW3zuIGLJXuj8vf6lYEg==",
-            "requires": {
-                "@babel/runtime": "^7.4.2",
-                "@restart/context": "^2.1.4",
-                "@restart/hooks": "^0.3.21",
-                "@types/react": "^16.9.23",
-                "classnames": "^2.2.6",
-                "dom-helpers": "^5.1.2",
-                "invariant": "^2.2.4",
-                "prop-types": "^15.7.2",
-                "prop-types-extra": "^1.1.0",
-                "react-overlays": "^3.1.2",
-                "react-transition-group": "^4.0.0",
-                "uncontrollable": "^7.0.0",
-                "warning": "^4.0.3"
-            },
-            "dependencies": {
-                "dom-helpers": {
-                    "version": "5.1.4",
-                    "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz",
-                    "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==",
-                    "requires": {
-                        "@babel/runtime": "^7.8.7",
-                        "csstype": "^2.6.7"
-                    }
-                },
-                "react-transition-group": {
-                    "version": "4.3.0",
-                    "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.3.0.tgz",
-                    "integrity": "sha512-1qRV1ZuVSdxPlPf4O8t7inxUGpdyO5zG9IoNfJxSO0ImU2A1YWkEQvFPuIPZmMLkg5hYs7vv5mMOyfgSkvAwvw==",
-                    "requires": {
-                        "@babel/runtime": "^7.5.5",
-                        "dom-helpers": "^5.0.1",
-                        "loose-envify": "^1.4.0",
-                        "prop-types": "^15.6.2"
-                    }
-                },
-                "warning": {
-                    "version": "4.0.3",
-                    "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
-                    "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
-                    "requires": {
-                        "loose-envify": "^1.0.0"
-                    }
-                }
-            }
-        },
-        "react-bootstrap-dropdown-menu": {
-            "version": "1.1.15",
-            "resolved": "https://registry.npmjs.org/react-bootstrap-dropdown-menu/-/react-bootstrap-dropdown-menu-1.1.15.tgz",
-            "integrity": "sha512-o35fODF4GsNxEzmnRWZuoe29a6x3fXqRsLXOlAvS4d+TvO3yoLTM8iZnSZpJCkHQnjOOWRnGvDh5tryqJCKZ0w=="
-        },
         "react-color": {
             "version": "2.18.0",
             "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.18.0.tgz",
@@ -14506,14 +13680,6 @@
                 "warning": "^3.0.0"
             }
         },
-        "react-dimensions": {
-            "version": "1.3.1",
-            "resolved": "https://registry.npmjs.org/react-dimensions/-/react-dimensions-1.3.1.tgz",
-            "integrity": "sha512-go5vMuGUxaB5PiTSIk+ZfAxLbHwcIgIfLhkBZ2SIMQjaCgnpttxa30z5ijEzfDjeOCTGRpxvkzcmE4Vt4Ppvyw==",
-            "requires": {
-                "element-resize-event": "^2.0.4"
-            }
-        },
         "react-dom": {
             "version": "16.13.1",
             "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz",
@@ -14525,16 +13691,6 @@
                 "scheduler": "^0.19.1"
             }
         },
-        "react-golden-layout": {
-            "version": "1.0.6",
-            "resolved": "https://registry.npmjs.org/react-golden-layout/-/react-golden-layout-1.0.6.tgz",
-            "integrity": "sha512-KZQ17Bnd+LfyCqe2scVMznrGKTciX3VwoT3y4xn3Qok9hknCvVXZfXe2RSX5zNG7FlLJzWt0VWqy8qZBHpQVuQ==",
-            "requires": {
-                "golden-layout": "^1.5.9",
-                "react": "^16.3.0",
-                "react-dom": "^16.3.0"
-            }
-        },
         "react-image-lightbox-with-rotate": {
             "version": "5.1.1",
             "resolved": "https://registry.npmjs.org/react-image-lightbox-with-rotate/-/react-image-lightbox-with-rotate-5.1.1.tgz",
@@ -14582,60 +13738,17 @@
                 "resize-observer-polyfill": "^1.5.0"
             }
         },
-        "react-modal": {
-            "version": "3.11.2",
-            "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.11.2.tgz",
-            "integrity": "sha512-o8gvvCOFaG1T7W6JUvsYjRjMVToLZgLIsi5kdhFIQCtHxDkA47LznX62j+l6YQkpXDbvQegsDyxe/+JJsFQN7w==",
-            "requires": {
-                "exenv": "^1.2.0",
-                "prop-types": "^15.5.10",
-                "react-lifecycles-compat": "^3.0.0",
-                "warning": "^4.0.3"
-            },
-            "dependencies": {
-                "warning": {
-                    "version": "4.0.3",
-                    "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
-                    "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
-                    "requires": {
-                        "loose-envify": "^1.0.0"
-                    }
-                }
-            }
-        },
-        "react-mosaic": {
-            "version": "0.0.20",
-            "resolved": "https://registry.npmjs.org/react-mosaic/-/react-mosaic-0.0.20.tgz",
-            "integrity": "sha1-pSSr8uzyi5r2sh1NNQ/veCLvMJ4=",
+        "react-modal": {
+            "version": "3.11.2",
+            "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.11.2.tgz",
+            "integrity": "sha512-o8gvvCOFaG1T7W6JUvsYjRjMVToLZgLIsi5kdhFIQCtHxDkA47LznX62j+l6YQkpXDbvQegsDyxe/+JJsFQN7w==",
             "requires": {
-                "prop-types": "^15.6.0",
-                "threads": "^0.8.0"
-            }
-        },
-        "react-overlays": {
-            "version": "3.1.3",
-            "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-3.1.3.tgz",
-            "integrity": "sha512-FH82W0R9lFJm/YCTDeSvEKQxXyTaZmjMEQlAjRhgjQhknTkyMsft+X4Wep5l95QveqdxGVxl/P41WUOzTGJUcw==",
-            "requires": {
-                "@babel/runtime": "^7.4.5",
-                "@popperjs/core": "^2.0.0",
-                "@restart/hooks": "^0.3.12",
-                "@types/warning": "^3.0.0",
-                "dom-helpers": "^5.1.0",
-                "prop-types": "^15.7.2",
-                "uncontrollable": "^7.0.0",
+                "exenv": "^1.2.0",
+                "prop-types": "^15.5.10",
+                "react-lifecycles-compat": "^3.0.0",
                 "warning": "^4.0.3"
             },
             "dependencies": {
-                "dom-helpers": {
-                    "version": "5.1.4",
-                    "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz",
-                    "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==",
-                    "requires": {
-                        "@babel/runtime": "^7.8.7",
-                        "csstype": "^2.6.7"
-                    }
-                },
                 "warning": {
                     "version": "4.0.3",
                     "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
@@ -14646,33 +13759,6 @@
                 }
             }
         },
-        "react-simple-dropdown": {
-            "version": "3.2.3",
-            "resolved": "https://registry.npmjs.org/react-simple-dropdown/-/react-simple-dropdown-3.2.3.tgz",
-            "integrity": "sha512-NmyyvA0D4wph5ctzkn8U4wmblOacavJMl9gTOhQR3v8I997mc1FL1NFKkj3Mx+HNysBKRD/HI+kpxXCAgXumPw==",
-            "requires": {
-                "classnames": "^2.1.2",
-                "prop-types": "^15.5.8"
-            }
-        },
-        "react-split-pane": {
-            "version": "0.1.91",
-            "resolved": "https://registry.npmjs.org/react-split-pane/-/react-split-pane-0.1.91.tgz",
-            "integrity": "sha512-8U56HOKQGFlvXXT1PaHbijjYy2W8g0iQaHC99Q2aV4yYfvUURcRGyfPKN3scGkbYN2pvy3qyoEwHyewUmR1VbQ==",
-            "requires": {
-                "prop-types": "^15.7.2",
-                "react-lifecycles-compat": "^3.0.4",
-                "react-style-proptype": "^3.2.2"
-            }
-        },
-        "react-style-proptype": {
-            "version": "3.2.2",
-            "resolved": "https://registry.npmjs.org/react-style-proptype/-/react-style-proptype-3.2.2.tgz",
-            "integrity": "sha512-ywYLSjNkxKHiZOqNlso9PZByNEY+FTyh3C+7uuziK0xFXu9xzdyfHwg4S9iyiRRoPCR4k2LqaBBsWVmSBwCWYQ==",
-            "requires": {
-                "prop-types": "^15.5.4"
-            }
-        },
         "react-table": {
             "version": "6.11.5",
             "resolved": "https://registry.npmjs.org/react-table/-/react-table-6.11.5.tgz",
@@ -14813,24 +13899,6 @@
             "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz",
             "integrity": "sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw="
         },
-        "recast": {
-            "version": "0.11.23",
-            "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz",
-            "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=",
-            "requires": {
-                "ast-types": "0.9.6",
-                "esprima": "~3.1.0",
-                "private": "~0.1.5",
-                "source-map": "~0.5.0"
-            },
-            "dependencies": {
-                "esprima": {
-                    "version": "3.1.3",
-                    "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
-                    "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
-                }
-            }
-        },
         "rechoir": {
             "version": "0.6.2",
             "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
@@ -15001,6 +14069,11 @@
             "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
             "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
         },
+        "require-package-name": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz",
+            "integrity": "sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk="
+        },
         "require_optional": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
@@ -15097,14 +14170,6 @@
             "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
             "dev": true
         },
-        "right-align": {
-            "version": "0.1.3",
-            "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
-            "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
-            "requires": {
-                "align-text": "^0.1.1"
-            }
-        },
         "rimraf": {
             "version": "3.0.2",
             "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -15117,6 +14182,7 @@
             "version": "2.0.2",
             "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
             "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+            "dev": true,
             "requires": {
                 "hash-base": "^3.0.0",
                 "inherits": "^2.0.1"
@@ -15172,119 +14238,14 @@
             }
         },
         "sass-graph": {
-            "version": "2.2.4",
-            "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
-            "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
+            "version": "2.2.5",
+            "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz",
+            "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==",
             "requires": {
                 "glob": "^7.0.0",
                 "lodash": "^4.0.0",
                 "scss-tokenizer": "^0.2.3",
-                "yargs": "^7.0.0"
-            },
-            "dependencies": {
-                "ansi-regex": {
-                    "version": "2.1.1",
-                    "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-                    "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
-                },
-                "camelcase": {
-                    "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
-                    "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
-                },
-                "cliui": {
-                    "version": "3.2.0",
-                    "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
-                    "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
-                    "requires": {
-                        "string-width": "^1.0.1",
-                        "strip-ansi": "^3.0.1",
-                        "wrap-ansi": "^2.0.0"
-                    }
-                },
-                "get-caller-file": {
-                    "version": "1.0.3",
-                    "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
-                    "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="
-                },
-                "is-fullwidth-code-point": {
-                    "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
-                    "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
-                    "requires": {
-                        "number-is-nan": "^1.0.0"
-                    }
-                },
-                "require-main-filename": {
-                    "version": "1.0.1",
-                    "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
-                    "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
-                },
-                "string-width": {
-                    "version": "1.0.2",
-                    "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
-                    "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
-                    "requires": {
-                        "code-point-at": "^1.0.0",
-                        "is-fullwidth-code-point": "^1.0.0",
-                        "strip-ansi": "^3.0.0"
-                    }
-                },
-                "strip-ansi": {
-                    "version": "3.0.1",
-                    "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
-                    "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
-                    "requires": {
-                        "ansi-regex": "^2.0.0"
-                    }
-                },
-                "which-module": {
-                    "version": "1.0.0",
-                    "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
-                    "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8="
-                },
-                "wrap-ansi": {
-                    "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
-                    "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
-                    "requires": {
-                        "string-width": "^1.0.1",
-                        "strip-ansi": "^3.0.1"
-                    }
-                },
-                "y18n": {
-                    "version": "3.2.1",
-                    "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
-                    "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
-                },
-                "yargs": {
-                    "version": "7.1.0",
-                    "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
-                    "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
-                    "requires": {
-                        "camelcase": "^3.0.0",
-                        "cliui": "^3.2.0",
-                        "decamelize": "^1.1.1",
-                        "get-caller-file": "^1.0.1",
-                        "os-locale": "^1.4.0",
-                        "read-pkg-up": "^1.0.1",
-                        "require-directory": "^2.1.1",
-                        "require-main-filename": "^1.0.1",
-                        "set-blocking": "^2.0.0",
-                        "string-width": "^1.0.2",
-                        "which-module": "^1.0.0",
-                        "y18n": "^3.2.1",
-                        "yargs-parser": "^5.0.0"
-                    }
-                },
-                "yargs-parser": {
-                    "version": "5.0.0",
-                    "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
-                    "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
-                    "requires": {
-                        "camelcase": "^3.0.0"
-                    }
-                }
+                "yargs": "^13.3.2"
             }
         },
         "sass-loader": {
@@ -15375,11 +14336,6 @@
             "resolved": "https://registry.npmjs.org/section-iterator/-/section-iterator-2.0.0.tgz",
             "integrity": "sha1-v0RNev7rlK1Dw5rS+yYVFifMuio="
         },
-        "seedrandom": {
-            "version": "2.4.3",
-            "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz",
-            "integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw="
-        },
         "select-hose": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@@ -15408,6 +14364,11 @@
             "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
             "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
         },
+        "semver-compare": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+            "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w="
+        },
         "semver-diff": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
@@ -15576,6 +14537,7 @@
             "version": "2.4.11",
             "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
             "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+            "dev": true,
             "requires": {
                 "inherits": "^2.0.1",
                 "safe-buffer": "^5.0.1"
@@ -16169,14 +15131,6 @@
                 }
             }
         },
-        "split": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
-            "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
-            "requires": {
-                "through": "2"
-            }
-        },
         "split-on-first": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
@@ -16291,11 +15245,6 @@
             "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
             "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
         },
-        "stopword": {
-            "version": "0.3.5",
-            "resolved": "https://registry.npmjs.org/stopword/-/stopword-0.3.5.tgz",
-            "integrity": "sha512-PCuSvR3JNHwRuURj2hC7XNg+qz7XJIURKquQdbmKKl3L42gUEVckykp72zszPo8OnF4iv7I1QSHFMN7naJ6t7A=="
-        },
         "stream-browserify": {
             "version": "2.0.2",
             "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
@@ -16323,15 +15272,6 @@
                 }
             }
         },
-        "stream-combiner": {
-            "version": "0.2.2",
-            "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
-            "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=",
-            "requires": {
-                "duplexer": "~0.1.1",
-                "through": "~2.3.4"
-            }
-        },
         "stream-each": {
             "version": "1.2.3",
             "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
@@ -16616,11 +15556,6 @@
                 "readable-stream": "^3.1.1"
             }
         },
-        "tensorflow-models": {
-            "version": "0.0.1",
-            "resolved": "https://registry.npmjs.org/tensorflow-models/-/tensorflow-models-0.0.1.tgz",
-            "integrity": "sha512-ze61MpdblYag2nldtnBpFwspH312yXvO9qB5i3006YHKzO9xABUHPlmRcIOnUsKIEqXf3qfXeuNAvccYJuvoxA=="
-        },
         "term-size": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
@@ -16779,15 +15714,6 @@
                 }
             }
         },
-        "threads": {
-            "version": "0.8.1",
-            "resolved": "https://registry.npmjs.org/threads/-/threads-0.8.1.tgz",
-            "integrity": "sha1-40ARW1lHMW0vfuMSPEwsW/nHbXI=",
-            "requires": {
-                "eventemitter3": "^2.0.2",
-                "native-promise-only": "^0.8.1"
-            }
-        },
         "through": {
             "version": "2.3.8",
             "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
@@ -16909,11 +15835,6 @@
             "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
             "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
         },
-        "token-stream": {
-            "version": "0.0.1",
-            "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz",
-            "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo="
-        },
         "touch": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
@@ -16979,38 +15900,6 @@
             "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
             "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics="
         },
-        "ts-jest": {
-            "version": "24.3.0",
-            "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.3.0.tgz",
-            "integrity": "sha512-Hb94C/+QRIgjVZlJyiWwouYUF+siNJHJHknyspaOcZ+OQAIdFG/UrdQVXw/0B8Z3No34xkUXZJpOTy9alOWdVQ==",
-            "requires": {
-                "bs-logger": "0.x",
-                "buffer-from": "1.x",
-                "fast-json-stable-stringify": "2.x",
-                "json5": "2.x",
-                "lodash.memoize": "4.x",
-                "make-error": "1.x",
-                "mkdirp": "0.x",
-                "resolve": "1.x",
-                "semver": "^5.5",
-                "yargs-parser": "10.x"
-            },
-            "dependencies": {
-                "camelcase": {
-                    "version": "4.1.0",
-                    "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
-                    "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
-                },
-                "yargs-parser": {
-                    "version": "10.1.0",
-                    "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
-                    "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==",
-                    "requires": {
-                        "camelcase": "^4.1.0"
-                    }
-                }
-            }
-        },
         "ts-loader": {
             "version": "5.4.5",
             "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz",
@@ -17194,7 +16083,8 @@
         "type": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
-            "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
+            "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+            "dev": true
         },
         "type-check": {
             "version": "0.3.2",
@@ -17225,18 +16115,11 @@
             "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
             "dev": true
         },
-        "typedarray-to-buffer": {
-            "version": "3.1.5",
-            "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
-            "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
-            "requires": {
-                "is-typedarray": "^1.0.0"
-            }
-        },
         "typescript": {
             "version": "3.8.3",
             "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
-            "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w=="
+            "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
+            "dev": true
         },
         "typescript-collections": {
             "version": "1.3.3",
@@ -17253,50 +16136,6 @@
             "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz",
             "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ=="
         },
-        "uglify-js": {
-            "version": "2.8.29",
-            "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
-            "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
-            "requires": {
-                "source-map": "~0.5.1",
-                "uglify-to-browserify": "~1.0.0",
-                "yargs": "~3.10.0"
-            },
-            "dependencies": {
-                "camelcase": {
-                    "version": "1.2.1",
-                    "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
-                    "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk="
-                },
-                "cliui": {
-                    "version": "2.1.0",
-                    "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
-                    "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
-                    "requires": {
-                        "center-align": "^0.1.1",
-                        "right-align": "^0.1.1",
-                        "wordwrap": "0.0.2"
-                    }
-                },
-                "yargs": {
-                    "version": "3.10.0",
-                    "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
-                    "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
-                    "requires": {
-                        "camelcase": "^1.0.2",
-                        "cliui": "^2.1.0",
-                        "decamelize": "^1.0.0",
-                        "window-size": "0.1.0"
-                    }
-                }
-            }
-        },
-        "uglify-to-browserify": {
-            "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
-            "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
-            "optional": true
-        },
         "uid-safe": {
             "version": "2.1.5",
             "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
@@ -17319,17 +16158,6 @@
                 "through": "^2.3.8"
             }
         },
-        "uncontrollable": {
-            "version": "7.1.1",
-            "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.1.1.tgz",
-            "integrity": "sha512-EcPYhot3uWTS3w00R32R2+vS8Vr53tttrvMj/yA1uYRhf8hbTG2GyugGqWDY0qIskxn0uTTojVd6wPYW9ZEf8Q==",
-            "requires": {
-                "@babel/runtime": "^7.6.3",
-                "@types/react": "^16.9.11",
-                "invariant": "^2.2.4",
-                "react-lifecycles-compat": "^3.0.4"
-            }
-        },
         "undefsafe": {
             "version": "2.0.3",
             "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz",
@@ -17645,10 +16473,14 @@
             "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
             "dev": true
         },
-        "void-elements": {
-            "version": "2.0.1",
-            "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
-            "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w="
+        "vue-template-compiler": {
+            "version": "2.6.11",
+            "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz",
+            "integrity": "sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==",
+            "requires": {
+                "de-indent": "^1.0.2",
+                "he": "^1.1.0"
+            }
         },
         "w3c-hr-time": {
             "version": "1.0.2",
@@ -17675,6 +16507,11 @@
                 "xml-name-validator": "^3.0.0"
             }
         },
+        "walkdir": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz",
+            "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ=="
+        },
         "warning": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
@@ -18401,33 +17238,6 @@
                 "sdp": "^2.12.0"
             }
         },
-        "websocket": {
-            "version": "1.0.31",
-            "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.31.tgz",
-            "integrity": "sha512-VAouplvGKPiKFDTeCCO65vYHsyay8DqoBSlzIO3fayrfOgU94lQN5a1uWVnFrMLceTJw/+fQXR5PGbUVRaHshQ==",
-            "requires": {
-                "debug": "^2.2.0",
-                "es5-ext": "^0.10.50",
-                "nan": "^2.14.0",
-                "typedarray-to-buffer": "^3.1.5",
-                "yaeti": "^0.0.6"
-            },
-            "dependencies": {
-                "debug": {
-                    "version": "2.6.9",
-                    "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-                    "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-                    "requires": {
-                        "ms": "2.0.0"
-                    }
-                },
-                "ms": {
-                    "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
-                }
-            }
-        },
         "websocket-driver": {
             "version": "0.7.3",
             "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz",
@@ -18520,44 +17330,6 @@
                 "infobox-parser": "3.3.1"
             }
         },
-        "window-size": {
-            "version": "0.1.0",
-            "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
-            "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0="
-        },
-        "with": {
-            "version": "5.1.1",
-            "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz",
-            "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=",
-            "requires": {
-                "acorn": "^3.1.0",
-                "acorn-globals": "^3.0.0"
-            },
-            "dependencies": {
-                "acorn": {
-                    "version": "3.3.0",
-                    "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
-                    "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
-                }
-            }
-        },
-        "word-extractor": {
-            "version": "0.3.0",
-            "resolved": "https://registry.npmjs.org/word-extractor/-/word-extractor-0.3.0.tgz",
-            "integrity": "sha512-gFRsCojw2sijgoHXAa11b9K2OeEvajw4iQp89doDlseVYklR56Z22AlzDKeP1bo4N5wT/AJWptbcPQPstXVlsQ==",
-            "requires": {
-                "async": "^1.5.2",
-                "event-stream": "^3.3.4",
-                "underscore": "^1.8.3"
-            },
-            "dependencies": {
-                "async": {
-                    "version": "1.5.2",
-                    "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-                    "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
-                }
-            }
-        },
         "word-wrap": {
             "version": "1.2.3",
             "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
@@ -18574,11 +17346,6 @@
                 "its-set": "^1.1.5"
             }
         },
-        "wordwrap": {
-            "version": "0.0.2",
-            "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
-            "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
-        },
         "wordwrapjs": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
@@ -18681,14 +17448,6 @@
             "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
             "dev": true
         },
-        "xml2js": {
-            "version": "0.1.9",
-            "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.1.9.tgz",
-            "integrity": "sha1-wm/Qgm4Bor5xEHSKNPD4OFvkWfE=",
-            "requires": {
-                "sax": ">=0.1.1"
-            }
-        },
         "xmlchars": {
             "version": "2.2.0",
             "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
@@ -18724,11 +17483,6 @@
             "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
             "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
         },
-        "yaeti": {
-            "version": "0.0.6",
-            "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
-            "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc="
-        },
         "yallist": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
@@ -18823,34 +17577,6 @@
             "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=",
             "dev": true
         },
-        "youtube": {
-            "version": "0.1.0",
-            "resolved": "https://registry.npmjs.org/youtube/-/youtube-0.1.0.tgz",
-            "integrity": "sha1-lrAetv9uhdpQX7KcyM9jt9KD2ZU=",
-            "requires": {
-                "mime": "1.2.2",
-                "qs": "0.4.2",
-                "request": "2.1.1",
-                "xml2js": "0.1.9"
-            },
-            "dependencies": {
-                "mime": {
-                    "version": "1.2.2",
-                    "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.2.tgz",
-                    "integrity": "sha1-udY1W/U+jX1WaTEw5FHa/zQBSM8="
-                },
-                "qs": {
-                    "version": "0.4.2",
-                    "resolved": "https://registry.npmjs.org/qs/-/qs-0.4.2.tgz",
-                    "integrity": "sha1-PKxMhh43GoycR3CsI82o3mObjl8="
-                },
-                "request": {
-                    "version": "2.1.1",
-                    "resolved": "https://registry.npmjs.org/request/-/request-2.1.1.tgz",
-                    "integrity": "sha1-VXDgxzfWVuvW0dPICqUQ08+Gxvo="
-                }
-            }
-        },
         "zip-stream": {
             "version": "2.1.3",
             "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz",
diff --git a/package.json b/package.json
index 54a03d1be..1a92656bf 100644
--- a/package.json
+++ b/package.json
@@ -23,45 +23,6 @@
         "@types/react-dom": "^16.9.5",
         "@types/webpack-dev-middleware": "^2.0.2",
         "@types/webpack-hot-middleware": "^2.25.0",
-        "awesome-typescript-loader": "^5.2.1",
-        "chai": "^4.2.0",
-        "copy-webpack-plugin": "^4.6.0",
-        "cross-env": "^5.2.1",
-        "css-loader": "^2.1.1",
-        "dotenv": "^8.2.0",
-        "file-loader": "^3.0.1",
-        "fork-ts-checker-webpack-plugin": "^1.6.0",
-        "jsdom": "^15.2.1",
-        "mocha": "^5.2.0",
-        "sass-loader": "^7.3.1",
-        "scss-loader": "0.0.1",
-        "style-loader": "^0.23.1",
-        "ts-loader": "^5.3.3",
-        "ts-node": "^7.0.1",
-        "ts-node-dev": "^1.0.0-pre.44",
-        "tslint": "^5.20.1",
-        "tslint-loader": "^3.6.0",
-        "typescript": "^3.7.5",
-        "webpack": "^4.41.5",
-        "webpack-cli": "^3.3.10",
-        "webpack-dev-middleware": "^3.7.2",
-        "webpack-dev-server": "^3.10.1",
-        "webpack-hot-middleware": "^2.24.3"
-    },
-    "dependencies": {
-        "@fortawesome/fontawesome-free-solid": "^5.0.13",
-        "@fortawesome/fontawesome-svg-core": "^1.2.26",
-        "@fortawesome/free-brands-svg-icons": "^5.12.0",
-        "@fortawesome/free-regular-svg-icons": "^5.12.0",
-        "@fortawesome/free-solid-svg-icons": "^5.12.0",
-        "@fortawesome/react-fontawesome": "^0.1.8",
-        "@hig/flyout": "^1.2.0",
-        "@hig/theme-context": "^2.1.3",
-        "@hig/theme-data": "^2.13.0",
-        "@tensorflow-models/universal-sentence-encoder": "^1.2.2",
-        "@tensorflow/tfjs-converter": "^1.3.2",
-        "@tensorflow/tfjs-core": "^1.5.2",
-        "@trendmicro/react-dropdown": "^1.3.0",
         "@types/adm-zip": "^0.4.32",
         "@types/animejs": "^2.0.2",
         "@types/archiver": "^3.0.0",
@@ -69,12 +30,10 @@
         "@types/bcrypt-nodejs": "0.0.30",
         "@types/bluebird": "^3.5.29",
         "@types/body-parser": "^1.17.1",
-        "@types/classnames": "^2.2.8",
         "@types/color": "^3.0.1",
         "@types/connect-flash": "0.0.34",
         "@types/cookie-parser": "^1.4.2",
         "@types/cookie-session": "^2.0.36",
-        "@types/d3-format": "^1.3.1",
         "@types/dotenv": "^6.1.1",
         "@types/exif": "^0.6.0",
         "@types/express": "^4.17.2",
@@ -82,11 +41,8 @@
         "@types/express-session": "^1.15.16",
         "@types/express-validator": "^3.0.0",
         "@types/formidable": "^1.0.31",
-        "@types/gapi": "0.0.39",
         "@types/google-maps-react": "^2.0.4",
         "@types/jquery": "^3.3.31",
-        "@types/jquery-awesome-cursor": "^0.3.0",
-        "@types/jsonwebtoken": "^8.3.7",
         "@types/libxmljs": "^0.18.5",
         "@types/lodash": "^4.14.149",
         "@types/mobile-detect": "^1.3.4",
@@ -104,12 +60,10 @@
         "@types/prosemirror-keymap": "^1.0.1",
         "@types/prosemirror-menu": "^1.0.1",
         "@types/prosemirror-model": "^1.7.0",
-        "@types/prosemirror-schema-basic": "^1.0.1",
         "@types/prosemirror-schema-list": "^1.0.1",
         "@types/prosemirror-state": "^1.2.3",
         "@types/prosemirror-transform": "^1.1.1",
         "@types/prosemirror-view": "^1.11.2",
-        "@types/pug": "^2.0.4",
         "@types/puppeteer": "^2.1.0",
         "@types/rc-switch": "^1.9.0",
         "@types/react": "^16.9.19",
@@ -128,13 +82,44 @@
         "@types/uuid": "^3.4.6",
         "@types/valid-url": "^1.0.3",
         "@types/webpack": "^4.41.3",
-        "@types/word-extractor": "^0.3.0",
         "@types/xregexp": "^4.3.0",
-        "@types/youtube": "0.0.38",
+        "@types/youtube": "0.0.39",
+        "awesome-typescript-loader": "^5.2.1",
+        "chai": "^4.2.0",
+        "copy-webpack-plugin": "^4.6.0",
+        "cross-env": "^5.2.1",
+        "css-loader": "^2.1.1",
+        "dotenv": "^8.2.0",
+        "file-loader": "^3.0.1",
+        "fork-ts-checker-webpack-plugin": "^1.6.0",
+        "jsdom": "^15.2.1",
+        "mocha": "^5.2.0",
+        "sass-loader": "^7.3.1",
+        "scss-loader": "0.0.1",
+        "style-loader": "^0.23.1",
+        "ts-loader": "^5.3.3",
+        "ts-node": "^7.0.1",
+        "ts-node-dev": "^1.0.0-pre.44",
+        "tslint": "^5.20.1",
+        "tslint-loader": "^3.6.0",
+        "typescript": "^3.7.5",
+        "webpack": "^4.41.5",
+        "webpack-cli": "^3.3.10",
+        "webpack-dev-middleware": "^3.7.2",
+        "webpack-dev-server": "^3.10.1",
+        "webpack-hot-middleware": "^2.24.3"
+    },
+    "dependencies": {
+        "@fortawesome/fontawesome-svg-core": "^1.2.26",
+        "@fortawesome/free-regular-svg-icons": "^5.12.0",
+        "@fortawesome/free-solid-svg-icons": "^5.12.0",
+        "@fortawesome/react-fontawesome": "^0.1.8",
+        "@hig/flyout": "^1.2.0",
+        "@hig/theme-context": "^2.1.3",
+        "@hig/theme-data": "^2.13.0",
         "adm-zip": "^0.4.13",
         "archiver": "^3.1.1",
         "array-batcher": "^1.2.3",
-        "arxiv-api-node": "0.0.2",
         "async": "^2.6.2",
         "babel-runtime": "^6.26.0",
         "bcrypt-nodejs": "0.0.3",
@@ -151,18 +136,15 @@
         "cookie-parser": "^1.4.4",
         "cookie-session": "^2.0.0-rc.1",
         "cors": "^2.8.5",
-        "crypto-browserify": "^3.11.0",
-        "d3-format": "^1.4.3",
+        "depcheck": "^0.9.2",
         "exif": "^0.6.0",
         "express": "^4.16.4",
         "express-flash": "0.0.2",
         "express-session": "^1.17.0",
         "express-validator": "^5.3.1",
         "expressjs": "^1.0.1",
-        "feedparser": "^2.2.9",
         "find-in-files": "^0.5.0",
         "flexlayout-react": "^0.3.3",
-        "font-awesome": "^4.7.0",
         "formidable": "^1.2.1",
         "golden-layout": "^1.5.9",
         "google-auth-library": "^4.2.4",
@@ -173,16 +155,11 @@
         "html-to-image": "^0.1.0",
         "html-to-text": "^5.1.1",
         "i": "^0.3.6",
-        "ibm-watson": "^5.3.1",
         "image-data-uri": "^2.0.1",
         "image-size": "^0.7.5",
         "image-size-stream": "^1.1.0",
-        "imagesloaded": "^4.1.4",
-        "jquery-awesome-cursor": "^0.3.1",
         "js-datepicker": "^4.6.6",
         "jsonschema": "^1.2.5",
-        "jsonwebtoken": "^8.5.0",
-        "jsx-to-string": "^1.4.0",
         "libxmljs": "^0.19.7",
         "lodash": "^4.17.15",
         "mobile-detect": "^1.4.4",
@@ -192,11 +169,8 @@
         "mobx-utils": "^5.5.3",
         "mongodb": "^3.5.2",
         "mongoose": "^5.8.9",
-        "node-pre-gyp": "^0.14.0",
-        "node-sass": "^4.13.1",
+        "node-sass": "^4.14.1",
         "node-stream-zip": "^1.9.1",
-        "node-tesseract": "^0.2.7",
-        "node-tesseract-ocr": "^1.0.0",
         "nodemailer": "^5.1.1",
         "nodemon": "^1.19.4",
         "normalize.css": "^8.0.1",
@@ -209,37 +183,27 @@
         "pdfjs-dist": "^2.3.200",
         "probe-image-size": "^4.0.0",
         "prosemirror-commands": "^1.1.3",
-        "prosemirror-example-setup": "^1.1.2",
         "prosemirror-find-replace": "^0.9.0",
         "prosemirror-history": "^1.1.3",
+        "prosemirror-inputrules": "^1.1.2",
         "prosemirror-keymap": "^1.1.3",
         "prosemirror-model": "^1.9.1",
-        "prosemirror-schema-basic": "^1.1.2",
         "prosemirror-schema-list": "^1.1.2",
         "prosemirror-state": "^1.3.2",
         "prosemirror-transform": "^1.2.3",
         "prosemirror-view": "^1.13.8",
-        "pug": "^2.0.3",
         "puppeteer": "^3.1.0",
         "query-string": "^6.10.1",
         "raw-loader": "^1.0.0",
         "rc-switch": "^1.9.0",
         "react": "^16.12.0",
-        "react-anime": "^2.3.2",
         "react-autosuggest": "^9.4.3",
-        "react-bootstrap": "^1.0.0-beta.16",
-        "react-bootstrap-dropdown-menu": "^1.1.15",
         "react-color": "^2.18.0",
         "react-compound-slider": "^2.5.0",
-        "react-dimensions": "^1.3.1",
         "react-dom": "^16.12.0",
-        "react-golden-layout": "^1.0.6",
         "react-image-lightbox-with-rotate": "^5.1.1",
         "react-jsx-parser": "^1.21.0",
         "react-measure": "^2.2.4",
-        "react-mosaic": "0.0.20",
-        "react-simple-dropdown": "^3.2.3",
-        "react-split-pane": "^0.1.89",
         "react-table": "^6.11.5",
         "readline": "^1.3.0",
         "request": "^2.88.0",
@@ -252,8 +216,6 @@
         "socket.io-client": "^2.3.0",
         "solr-node": "^1.2.1",
         "standard-http-error": "^2.0.1",
-        "stopword": "^0.3.3",
-        "tensorflow-models": "0.0.1",
         "typescript-collections": "^1.3.3",
         "url-loader": "^1.1.2",
         "uuid": "^3.4.0",
@@ -261,10 +223,8 @@
         "web-request": "^1.0.7",
         "webrtc-adapter": "^7.3.0",
         "wikijs": "^6.0.1",
-        "word-extractor": "^0.3.0",
         "words-to-numbers": "^1.5.1",
         "xoauth2": "^1.2.0",
-        "xregexp": "^4.3.0",
-        "youtube": "^0.1.0"
+        "xregexp": "^4.3.0"
     }
 }
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index bd743c28e..05515e502 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -54,8 +54,6 @@ export namespace SelectionManager {
         manager.SelectDoc(docView, ctrlPressed);
     }
 
-    export function SetIsDragging(dragging: boolean) { runInAction(() => manager.IsDragging = dragging); }
-    export function GetIsDragging() { return manager.IsDragging; }
     // computed functions, such as used in IsSelected generate errors if they're called outside of a
     // reaction context.  Specifying the context with 'outsideReaction' allows an efficiency feature
     // to avoid unnecessary mobx invalidations when running inside a reaction.
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index e306279d5..8841f7307 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,6 +1,6 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
 import {
-    faTasks, faTrashAlt, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+    faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
     faTerminal, faToggleOn, faFile as fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
@@ -113,7 +113,7 @@ export class MainView extends React.Component {
             }
         }
 
-        library.add(faTasks, faTrashAlt, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+        library.add(faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
             faTerminal, faToggleOn, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard, fileSolid,
             faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
             faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 745476ef7..6f5a3dfe4 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -1,5 +1,3 @@
-import { library } from '@fortawesome/fontawesome-svg-core';
-import { faFile } from '@fortawesome/free-solid-svg-icons';
 import 'golden-layout/src/css/goldenlayout-base.css';
 import 'golden-layout/src/css/goldenlayout-dark-theme.css';
 import { action, computed, Lambda, observable, reaction, runInAction, trace } from "mobx";
@@ -31,7 +29,6 @@ import { DockingViewButtonSelector } from './ParentDocumentSelector';
 import React = require("react");
 import { CollectionViewType } from './CollectionView';
 import { SnappingManager } from '../../util/SnappingManager';
-library.add(faFile);
 const _global = (window /* browser */ || global /* node */) as any;
 
 @observer
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index d6cb174cc..1e3bf11de 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -1,6 +1,4 @@
 import React = require("react");
-import { library } from '@fortawesome/fontawesome-svg-core';
-import { faPalette } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
@@ -22,8 +20,6 @@ const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
 
-library.add(faPalette);
-
 interface CMVFieldRowProps {
     rows: () => number;
     headings: () => object[];
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 5f0e28db2..57f484214 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -14,7 +14,6 @@ import { List } from "../../../fields/List";
 import { numberRange } from "../../../Utils";
 import { ComputedField } from "../../../fields/ScriptField";
 import { listSpec } from "../../../fields/Schema";
-import { docs } from "googleapis/build/src/apis/docs";
 
 export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
     dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined;
diff --git a/src/client/views/nodes/ComparisonBox.scss b/src/client/views/nodes/ComparisonBox.scss
index 44965cf28..3d48d96e2 100644
--- a/src/client/views/nodes/ComparisonBox.scss
+++ b/src/client/views/nodes/ComparisonBox.scss
@@ -24,7 +24,7 @@
     .slide-bar { 
         position: absolute;
         height: 100%;
-        width: 10px;
+        width: 3px;
         display: inline-block;
         background: gray;
         cursor: ew-resize;
@@ -34,7 +34,7 @@
             height: 20px;
             width: 30px;
             bottom: 0px;
-            left: -6px;
+            left: -10.5px;
             .left-handle, .right-handle{
                 width: 15px;
             }
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index f133a2a68..7a4d40db1 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -65,8 +65,12 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps, C
         this.resizeUpdater?.();
     }
 
-    private registerSliding = (e: React.PointerEvent<HTMLDivElement>) => {
-        setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, emptyFunction);
+    private registerSliding = (e: React.PointerEvent<HTMLDivElement>, targetWidth: number) => {
+        setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, action(() => {
+            this._animating = true;
+            this.dataDoc.clipWidth = targetWidth;
+            setTimeout(action(() => this._animating = false), 1000);
+        }), false);
     }
 
     @action
@@ -85,37 +89,33 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps, C
         delete this.dataDoc[fieldKey];
     }
 
+    @observable _animating = false;
     render() {
         const beforeDoc = Cast(this.dataDoc.beforeDoc, Doc, null);
         const afterDoc = Cast(this.dataDoc.afterDoc, Doc, null);
         const clipWidth = NumCast(this.dataDoc.clipWidth);
         return (
             <div className={`comparisonBox${this.active() || SnappingManager.GetIsDragging() ? "-interactive" : ""}`}>
-                <div
-                    className="afterBox-cont"
-                    key={"after"}
+                <div className="afterBox-cont" key={"after"} onPointerDown={e => this.registerSliding(e, this.props.PanelWidth() - 5)}
                     ref={(ele) => {
                         this._afterDropDisposer?.();
                         this._afterDropDisposer = this.createDropTarget(ele, "afterDoc");
                     }}>
-                    {
-                        afterDoc ?
-                            <>
-                                <ContentFittingDocumentView {...this.props}
-                                    Document={afterDoc}
-                                    parentActive={this.props.active}
-                                />
-                                <div className="clear-button after" onClick={e => this.clearDoc(e, "afterDoc")}>
-                                    <FontAwesomeIcon className="clear-button after" icon={faTimes} size="sm" />
-                                </div>
-                            </>
-                            :
-                            <div className="placeholder">
-                                <FontAwesomeIcon className="upload-icon" icon={faCloudUploadAlt} size="lg" />
-                            </div>
-                    }
+                    {afterDoc ? <>
+                        <ContentFittingDocumentView {...this.props}
+                            Document={afterDoc}
+                            pointerEvents={false}
+                            parentActive={this.props.active}
+                        />
+                        <div className="clear-button after" onClick={e => this.clearDoc(e, "afterDoc")}>
+                            <FontAwesomeIcon className="clear-button after" icon={faTimes} size="sm" />
+                        </div>
+                    </> :
+                        <div className="placeholder">
+                            <FontAwesomeIcon className="upload-icon" icon={faCloudUploadAlt} size="lg" />
+                        </div>}
                 </div>
-                <div className="clip-div" style={{ width: clipWidth + "px" }}>
+                <div className="clip-div" onPointerDown={e => this.registerSliding(e, 5)} style={{ width: clipWidth + "px", transition: this._animating ? "all 1s" : undefined }}>
                     {/* wraps around before image and slider bar */}
                     <div
                         className="beforeBox-cont"
@@ -130,6 +130,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps, C
                                 <>
                                     <ContentFittingDocumentView {...this.props}
                                         Document={beforeDoc}
+                                        pointerEvents={false}
                                         parentActive={this.props.active} />
                                     <div className="clear-button before" onClick={e => this.clearDoc(e, "beforeDoc")}>
                                         <FontAwesomeIcon className="clear-button before" icon={faTimes} size="sm" />
@@ -143,15 +144,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps, C
                     </div>
                 </div>
 
-                <div className="slide-bar" style={{ left: `calc(${NumCast(this.dataDoc.clipWidth) * 100 / this.props.PanelWidth()}% - 5px)` }} onPointerDown={this.registerSliding}>
-                    <div className="slide-handle" >
-                        <div className="left-handle" onClick={() => this.dataDoc.clipWidth = 5}>
-                            <FontAwesomeIcon icon="caret-left" size="lg" />
-                        </div>
-                        <div className="right-handle" onClick={() => this.dataDoc.clipWidth = this.props.PanelWidth() - 5}>
-                            <FontAwesomeIcon icon="caret-right" size="lg" />
-                        </div>
-                    </div>
+                <div className="slide-bar" style={{ left: `calc(${NumCast(this.dataDoc.clipWidth) * 100 / this.props.PanelWidth()}% - 0.5px)` }}>
+                    <div className="slide-handle" />
                 </div>
             </div >);
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 8dbd0232b..993cabc36 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -12,7 +12,6 @@ import { listSpec } from "../../../fields/Schema";
 import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
 import { ScriptField } from '../../../fields/ScriptField';
 import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
-import { ImageField } from '../../../fields/URLField';
 import { TraceMobx } from '../../../fields/util';
 import { GestureUtils } from '../../../pen-gestures/GestureUtils';
 import { emptyFunction, OmitKeys, returnOne, returnTransparent, Utils, emptyPath } from "../../../Utils";
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 47e7607d6..77abfef1d 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -19,7 +19,6 @@ import { CognitiveServices, Confidence, Service, Tag } from '../../cognitive_ser
 import { Docs } from '../../documents/Documents';
 import { Networking } from '../../Network';
 import { DragManager } from '../../util/DragManager';
-import { SelectionManager } from '../../util/SelectionManager';
 import { undoBatch } from '../../util/UndoManager';
 import { ContextMenu } from "../../views/ContextMenu";
 import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index 2d27ec441..ad9e49369 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -1,5 +1,3 @@
-import { library } from '@fortawesome/fontawesome-svg-core';
-import { faEdit } from '@fortawesome/free-regular-svg-icons';
 import { action } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -16,9 +14,6 @@ import { ViewBoxBaseComponent } from '../DocComponent';
 import { FieldView, FieldViewProps } from './FieldView';
 import './LabelBox.scss';
 
-
-library.add(faEdit as any);
-
 const LabelSchema = createSchema({});
 
 type LabelDocument = makeInterface<[typeof LabelSchema, typeof documentSchema]>;
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 80b8e7840..aeb77a894 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -1,6 +1,6 @@
 import React = require("react");
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
+import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, DocListCast, DocCastAsync } from "../../../fields/Doc";
 import { InkTool } from "../../../fields/InkField";
@@ -15,8 +15,7 @@ import { InkingControl } from "../InkingControl";
 import { FieldView, FieldViewProps } from './FieldView';
 import "./PresBox.scss";
 import { ViewBoxBaseComponent } from "../DocComponent";
-import { makeInterface, listSpec } from "../../../fields/Schema";
-import { List } from "../../../fields/List";
+import { makeInterface } from "../../../fields/Schema";
 import { Docs } from "../../documents/Documents";
 import { PrefetchProxy } from "../../../fields/Proxy";
 import { ScriptField } from "../../../fields/ScriptField";
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 6b1e6ae18..9d02239fc 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -1,6 +1,4 @@
 import React = require("react");
-import { library } from "@fortawesome/fontawesome-svg-core";
-import { faVideo } from "@fortawesome/free-solid-svg-icons";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, IReactionDisposer, observable, reaction, runInAction, untracked } from "mobx";
 import { observer } from "mobx-react";
@@ -8,7 +6,6 @@ import * as rp from 'request-promise';
 import { Doc } from "../../../fields/Doc";
 import { InkTool } from "../../../fields/InkField";
 import { createSchema, makeInterface } from "../../../fields/Schema";
-import { ScriptField } from "../../../fields/ScriptField";
 import { Cast, StrCast } from "../../../fields/Types";
 import { VideoField } from "../../../fields/URLField";
 import { Utils, emptyFunction, returnOne, returnZero } from "../../../Utils";
@@ -31,8 +28,6 @@ export const timeSchema = createSchema({
 type VideoDocument = makeInterface<[typeof documentSchema, typeof timeSchema]>;
 const VideoDocument = makeInterface(documentSchema, timeSchema);
 
-library.add(faVideo);
-
 @observer
 export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoDocument>(VideoDocument) {
     static _youtubeIframeCounter: number = 0;
@@ -181,8 +176,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
 
     componentWillUnmount() {
         this.Pause();
-        this._reactionDisposer && this._reactionDisposer();
-        this._youtubeReactionDisposer && this._youtubeReactionDisposer();
+        this._reactionDisposer?.();
+        this._youtubeReactionDisposer?.();
     }
 
     @action
diff --git a/src/client/views/search/CheckBox.tsx b/src/client/views/search/CheckBox.tsx
index 8c97d5dbc..0a1e551ec 100644
--- a/src/client/views/search/CheckBox.tsx
+++ b/src/client/views/search/CheckBox.tsx
@@ -2,7 +2,6 @@ import * as React from 'react';
 import { observer } from 'mobx-react';
 import { observable, action, runInAction, IReactionDisposer, reaction } from 'mobx';
 import "./CheckBox.scss";
-import * as anime from 'animejs';
 
 interface CheckBoxProps {
     originalStatus: boolean;
diff --git a/tsconfig.json b/tsconfig.json
index 75541abca..803245ca6 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -13,6 +13,12 @@
         "lib": [
             "dom",
             "es2015"
+        ],
+        "typeRoots": [
+            "node_modules/@types"
+        ],
+        "types": [
+            "youtube"
         ]
     },
     // "exclude": [
-- 
cgit v1.2.3-70-g09d2


From 85c052837d21eb48b3a4f1fa7c95db6703b217d1 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 22 May 2020 00:59:42 -0400
Subject: got rid of renderLock for piles.  fixed drag/drop on piles to place
 things correctly.  made piles store their layoutEngine as a field.  fixed
 layout  of piled docs.

---
 .../views/collections/CollectionPileView.scss      |  3 ++
 .../views/collections/CollectionPileView.tsx       | 59 ++++++++++++----------
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  2 +-
 src/client/views/nodes/DocumentView.tsx            | 16 ++++--
 src/fields/Doc.ts                                  | 44 ++++++++--------
 5 files changed, 70 insertions(+), 54 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/collections/CollectionPileView.scss b/src/client/views/collections/CollectionPileView.scss
index ac874b663..48d07e42b 100644
--- a/src/client/views/collections/CollectionPileView.scss
+++ b/src/client/views/collections/CollectionPileView.scss
@@ -5,4 +5,7 @@
     height: 100%;
     width: 100%;
     overflow: visible;
+    .collectionPileView-innards {
+        width:100%;
+    }
 }
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx
index e3bcf2a21..020a87b2e 100644
--- a/src/client/views/collections/CollectionPileView.tsx
+++ b/src/client/views/collections/CollectionPileView.tsx
@@ -1,18 +1,17 @@
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { HeightSym, Opt, WidthSym } from "../../../fields/Doc";
+import { HeightSym, Opt, WidthSym, Doc } from "../../../fields/Doc";
 import { ScriptField } from "../../../fields/ScriptField";
 import { BoolCast, NumCast, StrCast } from "../../../fields/Types";
-import { ContextMenu } from "../ContextMenu";
-import { ContextMenuProps } from "../ContextMenuItem";
 import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView";
 import { CollectionSubView } from "./CollectionSubView";
 import "./CollectionPileView.scss";
 import React = require("react");
 import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../../Utils";
 import { SelectionManager } from "../../util/SelectionManager";
-import { UndoManager } from "../../util/UndoManager";
+import { UndoManager, undoBatch } from "../../util/UndoManager";
 import { SnappingManager } from "../../util/SnappingManager";
+import { DragManager } from "../../util/DragManager";
 
 @observer
 export class CollectionPileView extends CollectionSubView(doc => doc) {
@@ -20,10 +19,12 @@ export class CollectionPileView extends CollectionSubView(doc => doc) {
     _doubleTap: boolean | undefined = false;
     _originalChrome: string = "";
     @observable _contentsActive = true;
-    @observable _layoutEngine = "pass";
     @observable _collapsed: boolean = false;
     @observable _childClickedScript: Opt<ScriptField>;
     componentDidMount() {
+        if (this.layoutEngine() !== "pass" && this.layoutEngine() !== "starburst") {
+            this.Document._layoutEngine = "pass";
+        }
         this._originalChrome = StrCast(this.layoutDoc._chromeStatus);
         this.layoutDoc._chromeStatus = "disabled";
         this.layoutDoc.hideFilterView = true;
@@ -33,49 +34,54 @@ export class CollectionPileView extends CollectionSubView(doc => doc) {
         this.layoutDoc._chromeStatus = this._originalChrome;
     }
 
-    layoutEngine = () => this._layoutEngine;
+    layoutEngine = () => StrCast(this.Document._layoutEngine);
 
     @computed get contents() {
-        return <div className="collectionPileView-innards" style={{
-            width: "100%",
-            pointerEvents: this.layoutEngine() !== "pass" && (this.props.active() || this.layoutEngine() === "starburst") ? undefined : "none"
-        }} >
+        return <div className="collectionPileView-innards" style={{ pointerEvents: this.layoutEngine() === "starburst" ? undefined : "none" }} >
             <CollectionFreeFormView {...this.props} layoutEngine={this.layoutEngine} />
         </div>;
     }
-
-    specificMenu = (e: React.MouseEvent) => {
-        const layoutItems: ContextMenuProps[] = [];
-        const doc = this.props.Document;
-
-        ContextMenu.Instance.addItem({ description: "Options...", subitems: layoutItems, icon: "eye" });
-    }
-
     toggleStarburst = action(() => {
-        if (this._layoutEngine === 'starburst') {
+        if (this.layoutEngine() === 'starburst') {
             const defaultSize = 110;
             this.layoutDoc._overflow = undefined;
+            this.childDocs.forEach(d => Doc.iconify(d));
             this.rootDoc.x = NumCast(this.rootDoc.x) + this.layoutDoc[WidthSym]() / 2 - NumCast(this.layoutDoc._starburstPileWidth, defaultSize) / 2;
             this.rootDoc.y = NumCast(this.rootDoc.y) + this.layoutDoc[HeightSym]() / 2 - NumCast(this.layoutDoc._starburstPileHeight, defaultSize) / 2;
             this.layoutDoc._width = NumCast(this.layoutDoc._starburstPileWidth, defaultSize);
             this.layoutDoc._height = NumCast(this.layoutDoc._starburstPileHeight, defaultSize);
-            this._layoutEngine = 'pass';
+            Doc.pileup(this.childDocs);
+            this.layoutDoc._panX = 0;
+            this.layoutDoc._panY = -10;
+            this.props.Document._layoutEngine = 'pass';
         } else {
             const defaultSize = 25;
             this.layoutDoc._overflow = 'visible';
             !this.layoutDoc._starburstRadius && (this.layoutDoc._starburstRadius = 500);
             !this.layoutDoc._starburstDocScale && (this.layoutDoc._starburstDocScale = 2.5);
-            if (this._layoutEngine === 'pass') {
+            if (this.layoutEngine() === 'pass') {
                 this.rootDoc.x = NumCast(this.rootDoc.x) + this.layoutDoc[WidthSym]() / 2 - defaultSize / 2;
                 this.rootDoc.y = NumCast(this.rootDoc.y) + this.layoutDoc[HeightSym]() / 2 - defaultSize / 2;
                 this.layoutDoc._starburstPileWidth = this.layoutDoc[WidthSym]();
                 this.layoutDoc._starburstPileHeight = this.layoutDoc[HeightSym]();
             }
+            this.layoutDoc._panX = this.layoutDoc._panY = 0;
             this.layoutDoc._width = this.layoutDoc._height = defaultSize;
-            this._layoutEngine = 'starburst';
+            this.props.Document._layoutEngine = 'starburst';
         }
     });
 
+    @undoBatch
+    @action
+    onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
+        if (super.onInternalDrop(e, de)) {
+            if (de.complete.docDragData) {
+                Doc.pileup(this.childDocs);
+            }
+        }
+        return true;
+    }
+
     _undoBatch: UndoManager.Batch | undefined;
     pointerDown = (e: React.PointerEvent) => {
         let dist = 0;
@@ -107,20 +113,17 @@ export class CollectionPileView extends CollectionSubView(doc => doc) {
     }
 
     onClick = (e: React.MouseEvent) => {
-        if (e.button === 0 && (this._doubleTap || this.layoutEngine() === "starburst")) {
+        if (e.button === 0 && this._doubleTap) {
             SelectionManager.DeselectAll();
             this.toggleStarburst();
             e.stopPropagation();
         }
-        // else if (this.layoutEngine() === "pass") {
-        //     runInAction(() => this._contentsActive = false);
-        //     setTimeout(action(() => this._contentsActive = true), 300);
-        // }
     }
 
     render() {
 
-        return <div className={"collectionPileView"} onContextMenu={this.specificMenu} onClick={this.onClick} onPointerDown={this.pointerDown}
+        return <div className={"collectionPileView"} onClick={this.onClick} onPointerDown={this.pointerDown}
+            ref={this.createDashEventsTarget}
             style={{ width: this.props.PanelWidth(), height: `calc(100%  - ${this.props.Document._chromeStatus === "enabled" ? 51 : 0}px)` }}>
             {this.contents}
         </div>;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 9d880d294..1611b6935 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1363,7 +1363,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             {!this.Document._LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ?
                 this.placeholder : this.marqueeView}
             <CollectionFreeFormOverlayView elements={this.elementFunc} />
-            {this.isAnnotationOverlay || !this.props.isSelected() ? (null) :
+            {this.isAnnotationOverlay || !this.props.isSelected() || this.props.Document._viewType === CollectionViewType.Pile ? (null) :
                 <>
                     <div key="back" className="backKeyframe" onClick={this.prevKeyframe}>
                         <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 993cabc36..00d19752f 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1111,6 +1111,16 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }), 400);
     });
 
+    renderLock() {
+        return (this.Document.isBackground !== undefined || this.isSelected(false)) &&
+            ((this.Document.type === DocumentType.COL && this.Document._viewType !== CollectionViewType.Pile) || this.Document.type === DocumentType.IMG) &&
+            this.props.renderDepth > 0 && this.props.PanelWidth() > 0 ?
+            <div className="documentView-lock" onClick={() => this.toggleBackground(true)}>
+                <FontAwesomeIcon icon={this.Document.isBackground ? "unlock" : "lock"} style={{ color: this.Document.isBackground ? "red" : undefined }} size="lg" />
+            </div>
+            : (null);
+    }
+
     render() {
         if (!(this.props.Document instanceof Doc)) return (null);
         const backgroundColor = Doc.UserDoc().renderStyle === "comic" ? undefined : StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document);
@@ -1161,11 +1171,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 <div className="documentView-contentBlocker" />
             </> :
                 this.innards}
-            {(this.Document.isBackground !== undefined || this.isSelected(false)) && (this.Document.type === DocumentType.COL || this.Document.type === DocumentType.IMG) && this.props.renderDepth > 0 && this.props.PanelWidth() > 0 ?
-                <div className="documentView-lock" onClick={() => this.toggleBackground(true)}>
-                    <FontAwesomeIcon icon={this.Document.isBackground ? "unlock" : "lock"} style={{ color: this.Document.isBackground ? "red" : undefined }} size="lg" />
-                </div>
-                : (null)}
+            {this.renderLock()}
         </div>;
         { this._showKPQuery ? <KeyphraseQueryView keyphrases={this._queries}></KeyphraseQueryView> : undefined; }
     }
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 9f38f4369..1ea686cbb 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1028,28 +1028,32 @@ export namespace Doc {
         if (layoutKey && layoutKey !== "layout" && layoutKey !== "layout_icon") doc.deiconifyLayout = layoutKey.replace("layout_", "");
     }
 
-    export function pileup(selected: Doc[], x: number, y: number) {
-        const newCollection = Docs.Create.PileDocument(selected, { title: "pileup", x: x - 55, y: y - 55, _width: 110, _height: 100, _LODdisable: true });
+    export function pileup(docList: Doc[], x?: number, y?: number) {
         let w = 0, h = 0;
-        selected.forEach((d, i) => {
-            Doc.iconify(d);
-            w = Math.max(d[WidthSym](), w);
-            h = Math.max(d[HeightSym](), h);
-        });
-        h = Math.max(h, w * 4 / 3); // converting to an icon does not update the height right away.  so this is a fallback hack to try to do something reasonable
-        selected.forEach((d, i) => {
-            d.x = Math.cos(Math.PI * 2 * i / selected.length) * 10 - w / 2;
-            d.y = Math.sin(Math.PI * 2 * i / selected.length) * 10 - h / 2;
-            d.displayTimecode = undefined;  // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
+        runInAction(() => {
+            docList.forEach(d => {
+                Doc.iconify(d);
+                w = Math.max(d[WidthSym](), w);
+                h = Math.max(d[HeightSym](), h);
+            });
+            h = Math.max(h, w * 4 / 3); // converting to an icon does not update the height right away.  so this is a fallback hack to try to do something reasonable
+            docList.forEach((d, i) => {
+                d.x = Math.cos(Math.PI * 2 * i / docList.length) * 10 - w / 2;
+                d.y = Math.sin(Math.PI * 2 * i / docList.length) * 10 - h / 2;
+                d.displayTimecode = undefined;  // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
+            });
         });
-        newCollection.x = NumCast(newCollection.x) + NumCast(newCollection._width) / 2 - 55;
-        newCollection.y = NumCast(newCollection.y) + NumCast(newCollection._height) / 2 - 55;
-        newCollection._width = newCollection._height = 110;
-        //newCollection.borderRounding = "40px";
-        newCollection._jitterRotation = 10;
-        newCollection._backgroundColor = "gray";
-        newCollection._overflow = "visible";
-        return newCollection;
+        if (x !== undefined && y !== undefined) {
+            const newCollection = Docs.Create.PileDocument(docList, { title: "pileup", x: x - 55, y: y - 55, _width: 110, _height: 100, _LODdisable: true });
+            newCollection.x = NumCast(newCollection.x) + NumCast(newCollection._width) / 2 - 55;
+            newCollection.y = NumCast(newCollection.y) + NumCast(newCollection._height) / 2 - 55;
+            newCollection._width = newCollection._height = 110;
+            //newCollection.borderRounding = "40px";
+            newCollection._jitterRotation = 10;
+            newCollection._backgroundColor = "gray";
+            newCollection._overflow = "visible";
+            return newCollection;
+        }
     }
 
 
-- 
cgit v1.2.3-70-g09d2


From 895e84fe6999a39eb9553db68b378aee5c1864a3 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 29 May 2020 01:29:02 -0400
Subject: moved frame animation into freeform chrome.   fixed marquees of docs
 at non-zero frame.  fixed pile view to use its own _pileLayoutEngine key to
 avoid leaving colleciton in an animated state.  added toggle for snap linew
 views.  cached transforms in CollectionFreeformView for performance.

---
 src/client/views/MainView.tsx                      |   6 +-
 .../views/collections/CollectionPileView.tsx       |   8 +-
 .../views/collections/CollectionViewChromes.scss   |  60 +++++-
 .../views/collections/CollectionViewChromes.tsx    | 201 +++++++++++++--------
 .../collectionFreeForm/CollectionFreeFormView.scss |  26 ---
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  68 +++----
 .../collections/collectionFreeForm/MarqueeView.tsx |  12 +-
 src/client/views/nodes/DocumentView.tsx            |   9 +-
 src/client/views/nodes/PresBox.tsx                 |   3 -
 9 files changed, 223 insertions(+), 170 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 958ba0ce3..a0a6adab7 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -534,10 +534,10 @@ export class MainView extends React.Component {
     }
 
     @computed get snapLines() {
-        return <div className="mainView-snapLines">
+        return !Doc.UserDoc().showSnapLines ? (null) : <div className="mainView-snapLines">
             <svg style={{ width: "100%", height: "100%" }}>
-                {/* {SnappingManager.horizSnapLines().map(l => <line x1="0" y1={l} x2="2000" y2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)}
-                {SnappingManager.vertSnapLines().map(l => <line y1="0" x1={l} y2="2000" x2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)} */}
+                {SnappingManager.horizSnapLines().map(l => <line x1="0" y1={l} x2="2000" y2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)}
+                {SnappingManager.vertSnapLines().map(l => <line y1="0" x1={l} y2="2000" x2={l} stroke="black" opacity={0.3} strokeWidth={0.5} strokeDasharray={"1 1"} />)}
             </svg>
         </div>;
     }
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx
index 020a87b2e..fc48e0327 100644
--- a/src/client/views/collections/CollectionPileView.tsx
+++ b/src/client/views/collections/CollectionPileView.tsx
@@ -23,7 +23,7 @@ export class CollectionPileView extends CollectionSubView(doc => doc) {
     @observable _childClickedScript: Opt<ScriptField>;
     componentDidMount() {
         if (this.layoutEngine() !== "pass" && this.layoutEngine() !== "starburst") {
-            this.Document._layoutEngine = "pass";
+            this.Document._pileLayoutEngine = "pass";
         }
         this._originalChrome = StrCast(this.layoutDoc._chromeStatus);
         this.layoutDoc._chromeStatus = "disabled";
@@ -34,7 +34,7 @@ export class CollectionPileView extends CollectionSubView(doc => doc) {
         this.layoutDoc._chromeStatus = this._originalChrome;
     }
 
-    layoutEngine = () => StrCast(this.Document._layoutEngine);
+    layoutEngine = () => StrCast(this.Document._pileLayoutEngine);
 
     @computed get contents() {
         return <div className="collectionPileView-innards" style={{ pointerEvents: this.layoutEngine() === "starburst" ? undefined : "none" }} >
@@ -53,7 +53,7 @@ export class CollectionPileView extends CollectionSubView(doc => doc) {
             Doc.pileup(this.childDocs);
             this.layoutDoc._panX = 0;
             this.layoutDoc._panY = -10;
-            this.props.Document._layoutEngine = 'pass';
+            this.props.Document._pileLayoutEngine = 'pass';
         } else {
             const defaultSize = 25;
             this.layoutDoc._overflow = 'visible';
@@ -67,7 +67,7 @@ export class CollectionPileView extends CollectionSubView(doc => doc) {
             }
             this.layoutDoc._panX = this.layoutDoc._panY = 0;
             this.layoutDoc._width = this.layoutDoc._height = defaultSize;
-            this.props.Document._layoutEngine = 'starburst';
+            this.props.Document._pileLayoutEngine = 'starburst';
         }
     });
 
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index e4581eb46..03bd9a01a 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -8,10 +8,12 @@
     z-index: 9001;
     transition: top .5s;
     background: lightgrey;
+    transform-origin: top left;
 
     .collectionViewChrome {
         display: flex;
-        padding-bottom: 10px;
+        padding-bottom: 1px;
+        height:32px;
         border-bottom: .5px solid rgb(180, 180, 180);
         overflow: hidden;
 
@@ -21,12 +23,12 @@
             .collectionViewBaseChrome-viewPicker {
                 font-size: 75%;
                 //text-transform: uppercase;
-                letter-spacing: 2px;
+                //letter-spacing: 2px;
                 background: rgb(238, 238, 238);
                 color: grey;
                 outline-color: black;
                 border: none;
-                padding: 12px 10px 11px 10px;
+                //padding: 12px 10px 11px 10px;
             }
 
             .collectionViewBaseChrome-viewPicker:active {
@@ -47,6 +49,7 @@
             .collectionViewBaseChrome-cmdPicker {
                 margin-left: 3px;
                 margin-right: 0px;
+                font-size: 75%;
                 background: rgb(238, 238, 238);
                 border: none;
                 color: grey;
@@ -56,6 +59,7 @@
                 background-color: gray;
                 display: flex;
                 flex-direction: row;
+                height:30px;
                 .commandEntry-drop {
                     color:white;
                     width:25px;
@@ -95,8 +99,8 @@
                     margin: auto;
                     background: gray;
                     color: white;
-                    width: 40px;
-                    height: 40px;
+                    width: 30px;
+                    height: 30px;
                     align-items: center;
                     justify-content: center;
                 }
@@ -195,8 +199,7 @@
             .collectionTreeViewChrome-pivotField-label {
                 vertical-align: center;
                 padding-left: 10px;
-                padding-top: 10px;
-                padding-bottom: 10px;
+                margin:auto;
             }
 
             .collectionStackingViewChrome-pivotField,
@@ -204,14 +207,15 @@
                 color: white;
                 width:100%;
                 min-width: 100px;
-                text-align: center;
+                display: flex;
+                align-items: center;
                 background: rgb(238, 238, 238);
 
                 .editable-view-input,
                 input,
                 .editableView-container-editing-oneLine,
                 .editableView-container-editing {
-                    padding: 12px 10px 11px 10px;
+                    margin:auto;
                     border: 0px;
                     color: grey;
                     text-align: center;
@@ -235,6 +239,44 @@
     }
 }
 
+.collectionFreeFormViewChrome-cont {
+    width: 60px;
+    display: flex;
+    position: relative;
+    align-items: center;
+    .fwdKeyframe, .numKeyframe, .backKeyframe {
+        cursor: pointer;
+        position: absolute;
+        width: 20;
+        height: 30;
+        bottom: 0;
+        background: gray;
+        display: flex;
+        align-items: center;
+        color:white;
+    }
+    .backKeyframe {
+        left:0;
+        svg {
+            display:block;
+            margin:auto;
+        }
+    }
+    .numKeyframe {
+        left:20;
+        display: flex;
+        flex-direction: column;
+        padding: 5px;
+    }
+    .fwdKeyframe {
+        left:40;
+        svg {
+            display:block;
+            margin:auto;
+        }
+    }
+}
+
 .collectionSchemaViewChrome-cont {
     display: flex;
     font-size: 10.5px;
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 8c4d53d63..29a3e559a 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -15,6 +15,7 @@ import { COLLECTION_BORDER_WIDTH } from "../globalCssVariables.scss";
 import { CollectionViewType } from "./CollectionView";
 import { CollectionView } from "./CollectionView";
 import "./CollectionViewChromes.scss";
+import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
 const datepicker = require('js-datepicker');
 
 interface CollectionViewChromeProps {
@@ -44,7 +45,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
         initialize: emptyFunction,
     };
     _narrativeCommand = {
-        params: ["target", "source"], title: "=> click clicked open view",
+        params: ["target", "source"], title: "=> child click view",
         script: "this.target.childClickedOpenTemplateView = getDocTemplate(this.source?.[0])",
         immediate: (source: Doc[]) => this.target.childClickedOpenTemplateView = Doc.getDocTemplate(source?.[0]),
         initialize: emptyFunction,
@@ -83,22 +84,16 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
     private _viewRef = React.createRef<HTMLInputElement>();
     @observable private _currentKey: string = "";
 
-    componentDidMount = () => {
-        runInAction(() => {
-            // chrome status is one of disabled, collapsed, or visible. this determines initial state from document
-            const chromeStatus = this.props.CollectionView.props.Document._chromeStatus;
-            if (chromeStatus) {
-                if (chromeStatus === "disabled") {
-                    throw new Error("how did you get here, if chrome status is 'disabled' on a collection, a chrome shouldn't even be instantiated!");
-                }
-                else if (chromeStatus === "collapsed") {
-                    if (this.props.collapse) {
-                        this.props.collapse(true);
-                    }
-                }
-            }
-        });
-    }
+    componentDidMount = action(() => {
+        // chrome status is one of disabled, collapsed, or visible. this determines initial state from document
+        switch (this.props.CollectionView.props.Document._chromeStatus) {
+            case "disabled":
+                throw new Error("how did you get here, if chrome status is 'disabled' on a collection, a chrome shouldn't even be instantiated!");
+            case "collapsed":
+                this.props.collapse?.(true);
+                break;
+        }
+    })
 
     @undoBatch
     viewChanged = (e: React.ChangeEvent) => {
@@ -197,10 +192,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
         }
     }
 
-    subChrome = () => {
+    @computed get subChrome() {
         const collapsed = this.document._chromeStatus !== "enabled";
         if (collapsed) return null;
         switch (this.props.type) {
+            case CollectionViewType.Freeform: return (<CollectionFreeFormViewChrome key="collchrome" PanelWidth={this.props.PanelWidth} CollectionView={this.props.CollectionView} type={this.props.type} />);
             case CollectionViewType.Stacking: return (<CollectionStackingViewChrome key="collchrome" PanelWidth={this.props.PanelWidth} CollectionView={this.props.CollectionView} type={this.props.type} />);
             case CollectionViewType.Schema: return (<CollectionSchemaViewChrome key="collchrome" PanelWidth={this.props.PanelWidth} CollectionView={this.props.CollectionView} type={this.props.type} />);
             case CollectionViewType.Tree: return (<CollectionTreeViewChrome key="collchrome" PanelWidth={this.props.PanelWidth} CollectionView={this.props.CollectionView} type={this.props.type} />);
@@ -236,7 +232,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
             const vtype = this.props.CollectionView.collectionViewType;
             const c = {
                 params: ["target"], title: vtype,
-                script: `this.target._viewType = ${StrCast(this.props.CollectionView.props.Document._viewType)}`,
+                script: `this.target._viewType = '${StrCast(this.props.CollectionView.props.Document._viewType)}'`,
                 immediate: (source: Doc[]) => this.props.CollectionView.props.Document._viewType = Doc.getDocTemplate(source?.[0]),
                 initialize: emptyFunction,
             };
@@ -254,14 +250,61 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
         }, emptyFunction, emptyFunction);
     }
 
+    @computed get templateChrome() {
+        const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled";
+        return <div className="collectionViewBaseChrome-template" ref={this.createDropTarget} style={{ display: collapsed ? "none" : undefined }}>
+            <div className="commandEntry-outerDiv" title="drop document to apply or drag to create button" ref={this._commandRef} onPointerDown={this.dragCommandDown}>
+                <div className="commandEntry-drop">
+                    <FontAwesomeIcon icon="bullseye" size="2x" />
+                </div>
+                <select
+                    className="collectionViewBaseChrome-cmdPicker"
+                    onPointerDown={stopPropagation}
+                    onChange={this.commandChanged}
+                    value={this._currentKey}>
+                    <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key={"empty"} value={""} />
+                    {this._buttonizableCommands.map(cmd =>
+                        <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key={cmd.title} value={cmd.title}>{cmd.title}</option>
+                    )}
+                </select>
+            </div>
+        </div>;
+    }
+
+    @computed get viewModes() {
+        const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled";
+        return <div className="collectionViewBaseChrome-viewModes" style={{ display: collapsed ? "none" : undefined }}>
+            <div className="commandEntry-outerDiv" title="drop document to apply or drag to create button" ref={this._viewRef} onPointerDown={this.dragViewDown}>
+                <div className="commandEntry-drop">
+                    <FontAwesomeIcon icon="bullseye" size="2x" />
+                </div>
+                <select
+                    className="collectionViewBaseChrome-viewPicker"
+                    onPointerDown={stopPropagation}
+                    onChange={this.viewChanged}
+                    value={StrCast(this.props.CollectionView.props.Document._viewType)}>
+                    {Object.values(CollectionViewType).map(type => ["invalid", "docking"].includes(type) ? (null) : (
+                        <option
+                            key={Utils.GenerateGuid()}
+                            className="collectionViewBaseChrome-viewOption"
+                            onPointerDown={stopPropagation}
+                            value={type}>
+                            {type[0].toUpperCase() + type.substring(1)}
+                        </option>
+                    ))}
+                </select>
+            </div>
+        </div>;
+    }
+
     render() {
         const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled";
+        const scale = Math.min(1, this.props.CollectionView.props.ScreenToLocalTransform().Scale);
         return (
             <div className="collectionViewChrome-cont" style={{
                 top: collapsed ? -70 : 0, height: collapsed ? 0 : undefined,
-                transform: collapsed ? "" : `scale(${Math.min(1, this.props.CollectionView.props.ScreenToLocalTransform().Scale)})`,
-                transformOrigin: "top left",
-                width: `${this.props.PanelWidth() / Math.min(1, this.props.CollectionView.props.ScreenToLocalTransform().Scale)}px`
+                transform: collapsed ? "" : `scale(${scale})`,
+                width: `${this.props.PanelWidth() / scale}px`
             }}>
                 <div className="collectionViewChrome" style={{ border: "unset", pointerEvents: collapsed ? "none" : undefined }}>
                     <div className="collectionViewBaseChrome">
@@ -276,58 +319,71 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
                             title="Collapse collection chrome" onClick={this.toggleCollapse}>
                             <FontAwesomeIcon icon="caret-up" size="2x" />
                         </button>
-                        <div className="collectionViewBaseChrome-viewModes" style={{ display: collapsed ? "none" : undefined }}>
-                            <div className="commandEntry-outerDiv" title="drop document to apply or drag to create button" ref={this._viewRef} onPointerDown={this.dragViewDown}>
-                                <div className="commandEntry-drop">
-                                    <FontAwesomeIcon icon="bullseye" size="2x"></FontAwesomeIcon>
-                                </div>
-                                <select
-                                    className="collectionViewBaseChrome-viewPicker"
-                                    onPointerDown={stopPropagation}
-                                    onChange={this.viewChanged}
-                                    value={StrCast(this.props.CollectionView.props.Document._viewType)}>
-                                    {Object.values(CollectionViewType).map(type => ["invalid", "docking"].includes(type) ? (null) : (
-                                        <option
-                                            key={Utils.GenerateGuid()}
-                                            className="collectionViewBaseChrome-viewOption"
-                                            onPointerDown={stopPropagation}
-                                            value={type}>
-                                            {type[0].toUpperCase() + type.substring(1)}
-                                        </option>
-                                    ))}
-                                </select>
-                            </div>
-                        </div>
+                        {this.viewModes}
                         <div className="collectionViewBaseChrome-viewSpecs" title="filter documents to show" style={{ display: collapsed ? "none" : "grid" }}>
                             <div className="collectionViewBaseChrome-filterIcon" onPointerDown={this.toggleViewSpecs} >
                                 <FontAwesomeIcon icon="filter" size="2x" />
                             </div>
                         </div>
-                        <div className="collectionViewBaseChrome-template" ref={this.createDropTarget} style={{ display: collapsed ? "none" : undefined }}>
-                            <div className="commandEntry-outerDiv" title="drop document to apply or drag to create button" ref={this._commandRef} onPointerDown={this.dragCommandDown}>
-                                <div className="commandEntry-drop">
-                                    <FontAwesomeIcon icon="bullseye" size="2x" />
-                                </div>
-                                <select
-                                    className="collectionViewBaseChrome-cmdPicker"
-                                    onPointerDown={stopPropagation}
-                                    onChange={this.commandChanged}
-                                    value={this._currentKey}>
-                                    <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key={"empty"} value={""}>{""}</option>
-                                    {this._buttonizableCommands.map(cmd =>
-                                        <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} key={cmd.title} value={cmd.title}>{cmd.title}</option>
-                                    )}
-                                </select>
-                            </div>
-                        </div>
+                        {this.templateChrome}
                     </div>
-                    {this.subChrome()}
+                    {this.subChrome}
                 </div>
             </div>
         );
     }
 }
 
+@observer
+export class CollectionFreeFormViewChrome extends React.Component<CollectionViewChromeProps> {
+
+    get Document() { return this.props.CollectionView.props.Document; }
+    @computed get dataField() {
+        return this.props.CollectionView.props.Document[Doc.LayoutFieldKey(this.props.CollectionView.props.Document)];
+    }
+    @computed get childDocs() {
+        return DocListCast(this.dataField);
+    }
+    @undoBatch
+    @action
+    nextKeyframe = (): void => {
+        const currentFrame = NumCast(this.Document.currentFrame);
+        if (currentFrame === undefined) {
+            this.Document.currentFrame = 0;
+            CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0);
+        }
+        CollectionFreeFormDocumentView.updateKeyframe(this.childDocs, currentFrame || 0);
+        this.Document.currentFrame = Math.max(0, (currentFrame || 0) + 1);
+        this.Document.lastFrame = Math.max(NumCast(this.Document.currentFrame), NumCast(this.Document.lastFrame));
+    }
+    @undoBatch
+    @action
+    prevKeyframe = (): void => {
+        const currentFrame = NumCast(this.Document.currentFrame);
+        if (currentFrame === undefined) {
+            this.Document.currentFrame = 0;
+            CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0);
+        }
+        CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice());
+        this.Document.currentFrame = Math.max(0, (currentFrame || 0) - 1);
+    }
+    render() {
+        return this.Document.isAnnotationOverlay ? (null) :
+            <div className="collectionFreeFormViewChrome-cont">
+                <div key="back" title="back frame" className="backKeyframe" onClick={this.prevKeyframe}>
+                    <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
+                </div>
+                <div key="num" title="toggle view all" className="numKeyframe" style={{ backgroundColor: this.Document.editing ? "#759c75" : "#c56565" }}
+                    onClick={action(() => this.Document.editing = !this.Document.editing)} >
+                    {NumCast(this.Document.currentFrame)}
+                </div>
+                <div key="fwd" title="forward frame" className="fwdKeyframe" onClick={this.nextKeyframe}>
+                    <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
+                </div>
+            </div>;
+    }
+}
+
 @observer
 export class CollectionStackingViewChrome extends React.Component<CollectionViewChromeProps> {
     @observable private _currentKey: string = "";
@@ -474,19 +530,20 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionViewCh
 @observer
 export class CollectionTreeViewChrome extends React.Component<CollectionViewChromeProps> {
 
-    get dataExtension() {
-        return this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "_ext"] as Doc;
+    get sortAscending() {
+        return this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"];
     }
-    @computed private get descending() {
-        return this.dataExtension && Cast(this.dataExtension.sortAscending, "boolean", null);
+    set sortAscending(value) {
+        this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"] = value;
+    }
+    @computed private get ascending() {
+        return Cast(this.sortAscending, "boolean", null);
     }
 
     @action toggleSort = () => {
-        if (this.dataExtension) {
-            if (this.dataExtension.sortAscending) this.dataExtension.sortAscending = undefined;
-            else if (this.dataExtension.sortAscending === undefined) this.dataExtension.sortAscending = false;
-            else this.dataExtension.sortAscending = true;
-        }
+        if (this.sortAscending) this.sortAscending = undefined;
+        else if (this.sortAscending === undefined) this.sortAscending = false;
+        else this.sortAscending = true;
     }
 
     render() {
@@ -496,7 +553,7 @@ export class CollectionTreeViewChrome extends React.Component<CollectionViewChro
                     <div className="collectionTreeViewChrome-sortLabel">
                         Sort
                         </div>
-                    <div className="collectionTreeViewChrome-sortIcon" style={{ transform: `rotate(${this.descending === undefined ? "90" : this.descending ? "180" : "0"}deg)` }}>
+                    <div className="collectionTreeViewChrome-sortIcon" style={{ transform: `rotate(${this.ascending === undefined ? "90" : this.ascending ? "180" : "0"}deg)` }}>
                         <FontAwesomeIcon icon="caret-up" size="2x" color="white" />
                     </div>
                 </button>
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index 5478a1c4a..d9011c9d3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -41,32 +41,6 @@
     // touch action none means that the browser will handle none of the touch actions. this allows us to implement our own actions.
     touch-action: none;
 
-    .fwdKeyframe, .numKeyframe, .backKeyframe{
-        cursor: pointer;
-        position: absolute;
-        width: 20;
-        height:20;
-        bottom:0;
-        background:gray;
-    }
-    .backKeyframe {
-        right:45;
-        svg {
-            display:block;
-            margin:auto;
-        }
-    }
-    .numKeyframe {
-        right:25;
-        text-align:center;
-    }
-    .fwdKeyframe {
-        right:5;
-        svg {
-            display:block;
-            margin:auto;
-        }
-    }
 
     .collectionfreeformview-placeholder {
         background: gray;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index cb1228fed..c753a703d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,7 +1,7 @@
 import { library } from "@fortawesome/fontawesome-svg-core";
 import { faEye, faEyeSlash } 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, IReactionDisposer, observable, ObservableMap, reaction, runInAction, _allowStateChangesInsideComputed } from "mobx";
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, _allowStateChangesInsideComputed, trace } from "mobx";
 import { observer } from "mobx-react";
 import { computedFn } from "mobx-utils";
 import { Doc, HeightSym, Opt, WidthSym, DocListCast } from "../../../../fields/Doc";
@@ -118,12 +118,28 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             this.props.PanelWidth() / (this.contentBounds.r - this.contentBounds.x)) :
         this.Document.scale || 1)
 
-    private centeringShiftX = () => !this.isAnnotationOverlay ? this.props.PanelWidth() / 2 / this.parentScaling / this.contentScaling : 0;  // shift so pan position is at center of window for non-overlay collections
-    private centeringShiftY = () => !this.isAnnotationOverlay ? this.props.PanelHeight() / 2 / this.parentScaling / this.contentScaling : 0;// shift so pan position is at center of window for non-overlay collections
-    private getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth + 1, -this.borderWidth + 1).translate(-this.centeringShiftX(), -this.centeringShiftY()).transform(this.getLocalTransform());
-    private getTransformOverlay = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth + 1, -this.borderWidth + 1);
-    private getContainerTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth, -this.borderWidth);
-    private getLocalTransform = (): Transform => Transform.Identity().scale(1 / this.zoomScaling()).translate(this.panX(), this.panY());
+    @computed get cachedCenteringShiftX(): number {
+        return !this.isAnnotationOverlay ? this.props.PanelWidth() / 2 / this.parentScaling / this.contentScaling : 0;  // shift so pan position is at center of window for non-overlay collections
+    }
+    @computed get cachedCenteringShiftY(): number {
+        return !this.isAnnotationOverlay ? this.props.PanelHeight() / 2 / this.parentScaling / this.contentScaling : 0;// shift so pan position is at center of window for non-overlay collections
+    }
+    @computed get cachedGetLocalTransform(): Transform {
+        return Transform.Identity().scale(1 / this.zoomScaling()).translate(this.panX(), this.panY());
+    }
+    @computed get cachedGetContainerTransform(): Transform {
+        return this.props.ScreenToLocalTransform().translate(-this.borderWidth, -this.borderWidth);
+    }
+    @computed get cachedGetTransform(): Transform {
+        return this.getTransformOverlay().translate(- this.cachedCenteringShiftX, - this.cachedCenteringShiftY).transform(this.cachedGetLocalTransform);
+    }
+
+    private centeringShiftX = () => this.cachedCenteringShiftX;
+    private centeringShiftY = () => this.cachedCenteringShiftY;
+    private getTransform = () => this.cachedGetTransform.copy();
+    private getLocalTransform = () => this.cachedGetLocalTransform.copy();
+    private getContainerTransform = () => this.cachedGetContainerTransform.copy();
+    private getTransformOverlay = () => this.getContainerTransform().translate(1, 1);
     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
         this.addDocument(newBox);
@@ -162,30 +178,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         return retVal;
     })
 
-    @undoBatch
-    @action
-    nextKeyframe = (): void => {
-        const currentFrame = this.Document.currentFrame;
-        if (currentFrame === undefined) {
-            this.Document.currentFrame = 0;
-            CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0);
-        }
-        CollectionFreeFormDocumentView.updateKeyframe(this.childDocs, currentFrame || 0);
-        this.Document.currentFrame = Math.max(0, (currentFrame || 0) + 1);
-        this.Document.lastFrame = Math.max(NumCast(this.Document.currentFrame), NumCast(this.Document.lastFrame));
-    }
-    @undoBatch
-    @action
-    prevKeyframe = (): void => {
-        const currentFrame = this.Document.currentFrame;
-        if (currentFrame === undefined) {
-            this.Document.currentFrame = 0;
-            CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0);
-        }
-        CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice());
-        this.Document.currentFrame = Math.max(0, (currentFrame || 0) - 1);
-    }
-
     private selectDocuments = (docs: Doc[]) => {
         SelectionManager.DeselectAll();
         docs.map(doc => DocumentManager.Instance.getDocumentView(doc)).map(dv => dv && SelectionManager.SelectDoc(dv, true));
@@ -1219,6 +1211,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
 
         optionItems.push({ description: "reset view", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document.scale = 1; }, icon: "compress-arrows-alt" });
+        optionItems.push({ description: "toggle snap line display", event: () => Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" });
         optionItems.push({ description: "Reset default note style", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" });
         optionItems.push({ description: (!this.layoutDoc._nativeWidth || !this.layoutDoc._nativeHeight ? "Freeze" : "Unfreeze") + " Aspect", event: this.toggleNativeDimensions, icon: "snowflake" });
         optionItems.push({ description: `${this.fitToContent ? "Unset" : "Set"} Fit To Container`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
@@ -1397,18 +1390,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             {!this.Document._LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ?
                 this.placeholder : this.marqueeView}
             <CollectionFreeFormOverlayView elements={this.elementFunc} />
-            {this.isAnnotationOverlay || !this.props.isSelected() || this.props.Document._viewType === CollectionViewType.Pile ? (null) :
-                <>
-                    <div key="back" className="backKeyframe" onClick={this.prevKeyframe}>
-                        <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
-                    </div>
-                    <div key="num" className="numKeyframe" style={{ backgroundColor: this.Document.editing ? "#759c75" : "#c56565" }} onClick={action(() => this.Document.editing = !this.Document.editing)} >
-                        {NumCast(this.Document.currentFrame)}
-                    </div>
-                    <div key="fwd" className="fwdKeyframe" onClick={this.nextKeyframe}>
-                        <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
-                    </div>
-                </>}
+
             <div className={"pullpane-indicator"}
                 style={{
                     display: this._pullDirection ? "block" : "none",
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index ed70ac9e8..cdfeeaa6b 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -357,10 +357,14 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
         const selected = this.marqueeSelect(false);
         if (e instanceof KeyboardEvent ? e.key === "c" : true) {
             selected.map(action(d => {
-                //this.props.removeDocument(d);
-                d.x = NumCast(d.x) - bounds.left - bounds.width / 2;
-                d.y = NumCast(d.y) - bounds.top - bounds.height / 2;
-                d.displayTimecode = undefined;  // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
+                const dx = NumCast(d.x);
+                const dy = NumCast(d.y);
+                delete d.x;
+                delete d.y;
+                delete d.activeFrame;
+                delete d.displayTimecode;  // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
+                d.x = dx - bounds.left - bounds.width / 2;
+                d.y = dy - bounds.top - bounds.height / 2;
                 return d;
             }));
             this.props.removeDocument(selected);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 00d19752f..2de7b3460 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -965,9 +965,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         return this.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false;
     }
     childScaling = () => (this.layoutDoc._fitWidth ? this.props.PanelWidth() / this.nativeWidth : this.props.ContentScaling());
-    panelWidth = () => this.props.PanelWidth();
-    panelHeight = () => this.props.PanelHeight();
-    screenToLocalTransform = () => this.props.ScreenToLocalTransform();
     @computed get contents() {
         TraceMobx();
         return (<>
@@ -988,10 +985,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 addDocument={this.props.addDocument}
                 removeDocument={this.props.removeDocument}
                 moveDocument={this.props.moveDocument}
-                ScreenToLocalTransform={this.screenToLocalTransform}
+                ScreenToLocalTransform={this.props.ScreenToLocalTransform}
                 renderDepth={this.props.renderDepth}
-                PanelWidth={this.panelWidth}
-                PanelHeight={this.panelHeight}
+                PanelWidth={this.props.PanelWidth}
+                PanelHeight={this.props.PanelHeight}
                 ignoreAutoHeight={this.props.ignoreAutoHeight}
                 focus={this.props.focus}
                 parentActive={this.props.parentActive}
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 56a543f46..9f1e99c77 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -62,11 +62,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const lastFrame = Cast(presTargetDoc.lastFrame, "number", null);
         const curFrame = NumCast(presTargetDoc.currentFrame);
         if (lastFrame !== undefined && curFrame < lastFrame) {
-            //const docs = DocListCast(presTargetDoc[Doc.LayoutFieldKey(presTargetDoc)]);
             presTargetDoc.transition = "all 1s";
             setTimeout(() => presTargetDoc.transition = undefined, 1010);
-            // docs.forEach(doc => doc.transition = "all 1s");
-            // setTimeout(() => docs.forEach(doc => doc.transition = undefined), 1010);
             presTargetDoc.currentFrame = curFrame + 1;
         }
         else if (this.childDocs[this.itemIndex + 1] !== undefined) {
-- 
cgit v1.2.3-70-g09d2


From 5c4a948d506de2497d685f9ccba56ef6a855af1d Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 29 May 2020 21:52:00 -0400
Subject: added a version of client-side ACL's

---
 src/client/views/animationtimeline/Keyframe.tsx |  8 ++---
 src/client/views/collections/CollectionView.tsx | 16 ++++++----
 src/client/views/nodes/DocumentContentsView.tsx |  4 +--
 src/client/views/nodes/DocumentView.tsx         |  6 +++-
 src/fields/Doc.ts                               | 40 ++++++++++++++++++++++---
 src/fields/util.ts                              | 10 +++++--
 6 files changed, 66 insertions(+), 18 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx
index e3274fb35..b562bd957 100644
--- a/src/client/views/animationtimeline/Keyframe.tsx
+++ b/src/client/views/animationtimeline/Keyframe.tsx
@@ -180,10 +180,10 @@ export class Keyframe extends React.Component<IProps> {
             const fadeIn = this.props.makeKeyData(this.regiondata, this.regiondata.position + this.regiondata.fadeIn, KeyframeFunc.KeyframeType.fade);
             const fadeOut = this.props.makeKeyData(this.regiondata, this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut, KeyframeFunc.KeyframeType.fade);
             const finish = this.props.makeKeyData(this.regiondata, this.regiondata.position + this.regiondata.duration, KeyframeFunc.KeyframeType.end);
-            (fadeIn.key as Doc).opacity = 1;
-            (fadeOut.key as Doc).opacity = 1;
-            (start.key as Doc).opacity = 0.1;
-            (finish.key as Doc).opacity = 0.1;
+            (fadeIn as Doc).opacity = 1;
+            (fadeOut as Doc).opacity = 1;
+            (start as Doc).opacity = 0.1;
+            (finish as Doc).opacity = 0.1;
             this.forceUpdate(); //not needed, if setTimeout is gone...
         }, 1000);
     }
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index ee4755355..fecba32c5 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -8,7 +8,7 @@ import * as React from 'react';
 import Lightbox from 'react-image-lightbox-with-rotate';
 import 'react-image-lightbox-with-rotate/style.css'; // This only needs to be imported once in your app
 import { DateField } from '../../../fields/DateField';
-import { DataSym, Doc, DocListCast, Field, Opt } from '../../../fields/Doc';
+import { DataSym, Doc, DocListCast, Field, Opt, AclSym, AclAddonly, AclReadonly } from '../../../fields/Doc';
 import { List } from '../../../fields/List';
 import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from '../../../fields/Types';
 import { ImageField } from '../../../fields/URLField';
@@ -126,10 +126,16 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
         const docList = DocListCast(targetDataDoc[this.props.fieldKey]);
         const added = docs.filter(d => !docList.includes(d));
         if (added.length) {
-            added.map(doc => doc.context = this.props.Document);
-            added.map(add => Doc.AddDocToList(Cast(Doc.UserDoc().myCatalog, Doc, null), "data", add));
-            targetDataDoc[this.props.fieldKey] = new List<Doc>([...docList, ...added]);
-            targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
+            if (this.dataDoc[AclSym] === AclReadonly) {
+                return false;
+            } else if (this.dataDoc[AclSym] === AclAddonly) {
+                added.map(doc => Doc.AddDocToList(targetDataDoc, this.props.fieldKey, doc));
+            } else {
+                added.map(doc => doc.context = this.props.Document);
+                added.map(add => Doc.AddDocToList(Cast(Doc.UserDoc().myCatalog, Doc, null), "data", add));
+                targetDataDoc[this.props.fieldKey] = new List<Doc>([...docList, ...added]);
+                targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
+            }
         }
         return true;
     }
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index ef56e6fcd..126e9ac14 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -1,6 +1,6 @@
 import { computed } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, Opt, Field } from "../../../fields/Doc";
+import { Doc, Opt, Field, AclSym, AclPrivate } from "../../../fields/Doc";
 import { Cast, StrCast, NumCast } from "../../../fields/Types";
 import { OmitKeys, Without, emptyPath } from "../../../Utils";
 import DirectoryImportBox from "../../util/Import & Export/DirectoryImportBox";
@@ -185,7 +185,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
         const bindings = this.CreateBindings(onClick, onInput);
         //  layoutFrame = splits.length > 1 ? splits[0] + splits[1].replace(/{([^{}]|(?R))*}/, replacer4) : ""; // might have been more elegant if javascript supported recursive patterns
 
-        return (this.props.renderDepth > 12 || !layoutFrame || !this.layoutDoc) ? (null) :
+        return (this.props.renderDepth > 12 || !layoutFrame || !this.layoutDoc || this.layoutDoc[AclSym] === AclPrivate) ? (null) :
             <ObserverJsxParser
                 key={42}
                 blacklistedAttrs={[]}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 2de7b3460..7a4ecfa9c 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -4,7 +4,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import * as rp from "request-promise";
-import { Doc, DocListCast, HeightSym, Opt, WidthSym, DataSym } from "../../../fields/Doc";
+import { Doc, DocListCast, HeightSym, Opt, WidthSym, DataSym, AclSym, AclReadonly, AclPrivate } from "../../../fields/Doc";
 import { Document } from '../../../fields/documentSchemas';
 import { Id } from '../../../fields/FieldSymbols';
 import { InkTool } from '../../../fields/InkField';
@@ -742,6 +742,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
         const more = cm.findByDescription("More...");
         const moreItems: ContextMenuProps[] = more && "subitems" in more ? more.subitems : [];
+        moreItems.push({ description: "Make Add Only", event: () => this.layoutDoc.ACL = this.dataDoc.ACL = "addOnly", icon: "concierge-bell" });
+        moreItems.push({ description: "Make Read Only", event: () => this.layoutDoc.ACL = this.dataDoc.ACL = "readOnly", icon: "concierge-bell" });
+        moreItems.push({ description: "Make Private", event: () => this.layoutDoc[AclSym] = this.dataDoc[AclSym] = "noAccess", icon: "concierge-bell" });
         moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" });
         moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" });
         moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" });
@@ -1119,6 +1122,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     }
 
     render() {
+        if (this.props.Document[AclSym] && this.props.Document[AclSym] === AclPrivate) return (null);
         if (!(this.props.Document instanceof Doc)) return (null);
         const backgroundColor = Doc.UserDoc().renderStyle === "comic" ? undefined : StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document);
         const opacity = Cast(this.layoutDoc._opacity, "number", Cast(this.layoutDoc.opacity, "number", Cast(this.Document.opacity, "number", null)));
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 1ea686cbb..6891bf652 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -93,13 +93,40 @@ export const WidthSym = Symbol("Width");
 export const HeightSym = Symbol("Height");
 export const DataSym = Symbol("Data");
 export const LayoutSym = Symbol("Layout");
+export const AclSym = Symbol("Acl");
+export const AclPrivate = Symbol("AclNoAccess");
+export const AclReadonly = Symbol("AclReadOnly");
+export const AclAddonly = Symbol("AclAddonly");
 export const UpdatingFromServer = Symbol("UpdatingFromServer");
 const CachedUpdates = Symbol("Cached updates");
 
 
 function fetchProto(doc: Doc) {
+    if (doc.author !== Doc.CurrentUserEmail) {
+        if (doc.ACL === "noAccess") {
+            doc[AclSym] = AclPrivate;
+            return undefined;
+        } else if (doc.ACL === "readOnly") {
+            doc[AclSym] = AclReadonly;
+        } else if (doc.ACL === "addOnly") {
+            doc[AclSym] = AclAddonly;
+        }
+    }
+
     const proto = doc.proto;
     if (proto instanceof Promise) {
+        proto.then(proto => {
+            if (proto.author !== Doc.CurrentUserEmail) {
+                if (proto.ACL === "noAccess") {
+                    proto[AclSym] = doc[AclSym] = AclPrivate;
+                    return undefined;
+                } else if (proto.ACL === "readOnly") {
+                    proto[AclSym] = doc[AclSym] = AclReadonly;
+                } else if (proto.ACL === "addOnly") {
+                    proto[AclSym] = doc[AclSym] = AclAddonly;
+                }
+            }
+        });
         return proto;
     }
 }
@@ -113,10 +140,10 @@ export class Doc extends RefField {
             set: setter,
             get: getter,
             // getPrototypeOf: (target) => Cast(target[SelfProxy].proto, Doc) || null, // TODO this might be able to replace the proto logic in getter
-            has: (target, key) => key in target.__fields,
+            has: (target, key) => target[AclSym] !== AclPrivate && key in target.__fields,
             ownKeys: target => {
                 const obj = {} as any;
-                Object.assign(obj, target.___fields);
+                (target[AclSym] !== AclPrivate) && Object.assign(obj, target.___fields);
                 runInAction(() => obj.__LAYOUT__ = target.__LAYOUT__);
                 return Object.keys(obj);
             },
@@ -170,8 +197,11 @@ export class Doc extends RefField {
 
     private [Self] = this;
     private [SelfProxy]: any;
+    public [AclSym]: any = undefined;
     public [WidthSym] = () => NumCast(this[SelfProxy]._width);
     public [HeightSym] = () => NumCast(this[SelfProxy]._height);
+    public [ToScriptString]() { return `DOC-"${this[Self][Id]}"-`; }
+    public [ToString]() { return `Doc(${this[AclSym] === AclPrivate ? "-inaccessible-" : this.title})`; }
     public get [LayoutSym]() { return this[SelfProxy].__LAYOUT__; }
     public get [DataSym]() {
         const self = this[SelfProxy];
@@ -193,8 +223,6 @@ export class Doc extends RefField {
         return undefined;
     }
 
-    [ToScriptString]() { return `DOC-"${this[Self][Id]}"-`; }
-    [ToString]() { return `Doc(${this.title})`; }
 
     private [CachedUpdates]: { [key: string]: () => void | Promise<any> } = {};
     public static CurrentUserEmail: string = "";
@@ -794,6 +822,7 @@ export namespace Doc {
     }
     // don't bother memoizing (caching) the result if called from a non-reactive context. (plus this avoids a warning message)
     export function IsBrushedDegreeUnmemoized(doc: Doc) {
+        if (!doc || doc[AclSym] === AclPrivate || Doc.GetProto(doc)[AclSym] === AclPrivate) return 0;
         return brushManager.BrushedDoc.has(doc) ? 2 : brushManager.BrushedDoc.has(Doc.GetProto(doc)) ? 1 : 0;
     }
     export function IsBrushedDegree(doc: Doc) {
@@ -802,11 +831,13 @@ export namespace Doc {
         })(doc);
     }
     export function BrushDoc(doc: Doc) {
+        if (!doc || doc[AclSym] === AclPrivate || Doc.GetProto(doc)[AclSym] === AclPrivate) return doc;
         brushManager.BrushedDoc.set(doc, true);
         brushManager.BrushedDoc.set(Doc.GetProto(doc), true);
         return doc;
     }
     export function UnBrushDoc(doc: Doc) {
+        if (!doc || doc[AclSym] === AclPrivate || Doc.GetProto(doc)[AclSym] === AclPrivate) return doc;
         brushManager.BrushedDoc.delete(doc);
         brushManager.BrushedDoc.delete(Doc.GetProto(doc));
         return doc;
@@ -836,6 +867,7 @@ export namespace Doc {
     }
     const highlightManager = new HighlightBrush();
     export function IsHighlighted(doc: Doc) {
+        if (!doc || doc[AclSym] === AclPrivate || Doc.GetProto(doc)[AclSym] === AclPrivate) return false;
         return highlightManager.HighlightedDoc.get(doc) || highlightManager.HighlightedDoc.get(Doc.GetProto(doc));
     }
     export function HighlightDoc(doc: Doc, dataAndDisplayDocs = true) {
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 024c0f80e..54e7eca28 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -1,5 +1,5 @@
 import { UndoManager } from "../client/util/UndoManager";
-import { Doc, Field, FieldResult, UpdatingFromServer, LayoutSym } from "./Doc";
+import { Doc, Field, FieldResult, UpdatingFromServer, LayoutSym, AclSym, AclPrivate } from "./Doc";
 import { SerializationHelper } from "../client/util/SerializationHelper";
 import { ProxyField, PrefetchProxy } from "./Proxy";
 import { RefField } from "./RefField";
@@ -106,6 +106,7 @@ const layoutProps = ["panX", "panY", "width", "height", "nativeWidth", "nativeHe
     "LODdisable", "chromeStatus", "viewType", "gridGap", "xMargin", "yMargin", "autoHeight"];
 export function setter(target: any, in_prop: string | symbol | number, value: any, receiver: any): boolean {
     let prop = in_prop;
+    if (target[AclSym]) return true;
     if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && (prop.startsWith("_") || layoutProps.includes(prop))) {
         if (!prop.startsWith("_")) {
             console.log(prop + " is deprecated - switch to _" + prop);
@@ -124,6 +125,8 @@ export function setter(target: any, in_prop: string | symbol | number, value: an
 
 export function getter(target: any, in_prop: string | symbol | number, receiver: any): any {
     let prop = in_prop;
+    if (in_prop === AclSym) return target[AclSym];
+    if (target[AclSym] === AclPrivate) return undefined;
     if (prop === LayoutSym) {
         return target.__LAYOUT__;
     }
@@ -148,6 +151,9 @@ export function getter(target: any, in_prop: string | symbol | number, receiver:
 
 function getFieldImpl(target: any, prop: string | number, receiver: any, ignoreProto: boolean = false): any {
     receiver = receiver || target[SelfProxy];
+    if (target === undefined) {
+        console.log("");
+    }
     let field = target.__fields[prop];
     for (const plugin of getterPlugins) {
         const res = plugin(receiver, prop, field);
@@ -160,7 +166,7 @@ function getFieldImpl(target: any, prop: string | number, receiver: any, ignoreP
     }
     if (field === undefined && !ignoreProto && prop !== "proto") {
         const proto = getFieldImpl(target, "proto", receiver, true);//TODO tfs: instead of receiver we could use target[SelfProxy]... I don't which semantics we want or if it really matters
-        if (proto instanceof Doc) {
+        if (proto instanceof Doc && proto[AclSym] !== AclPrivate) {
             return getFieldImpl(proto[Self], prop, receiver, ignoreProto);
         }
         return undefined;
-- 
cgit v1.2.3-70-g09d2


From dc42fe7c83b86a53839994f2eae1ef545fbd5a9d Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 30 May 2020 21:17:55 -0400
Subject: fixed private ACL. added event so that crhome extension can tell Dash
 which document to navigate to.

---
 package-lock.json                       | 88 +++++++++++++++++++++++++++++++++
 package.json                            |  2 +
 src/client/util/DocumentManager.ts      | 14 +++---
 src/client/views/MainView.tsx           | 10 ++++
 src/client/views/nodes/DocumentView.tsx |  8 +--
 5 files changed, 111 insertions(+), 11 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/package-lock.json b/package-lock.json
index 21e4c4e27..842553659 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -412,6 +412,15 @@
             "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==",
             "dev": true
         },
+        "@types/chrome": {
+            "version": "0.0.114",
+            "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.114.tgz",
+            "integrity": "sha512-i7qRr74IrxHtbnrZSKUuP5Uvd5EOKwlwJq/yp7+yTPihOXnPhNQO4Z5bqb1XTnrjdbUKEJicaVVbhcgtRijmLA==",
+            "requires": {
+                "@types/filesystem": "*",
+                "@types/har-format": "*"
+            }
+        },
         "@types/color": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.1.tgz",
@@ -547,6 +556,19 @@
                 "express-validator": "*"
             }
         },
+        "@types/filesystem": {
+            "version": "0.0.29",
+            "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.29.tgz",
+            "integrity": "sha512-85/1KfRedmfPGsbK8YzeaQUyV1FQAvMPMTuWFQ5EkLd2w7szhNO96bk3Rh/SKmOfd9co2rCLf0Voy4o7ECBOvw==",
+            "requires": {
+                "@types/filewriter": "*"
+            }
+        },
+        "@types/filewriter": {
+            "version": "0.0.28",
+            "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.28.tgz",
+            "integrity": "sha1-wFTor02d11205jq8dviFFocU1LM="
+        },
         "@types/formidable": {
             "version": "1.0.31",
             "resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-1.0.31.tgz",
@@ -584,6 +606,11 @@
             "integrity": "sha512-L8O9HAVFZj0TuiS8h5ORthiMsrrhjxTC8XUusp5k47oXCst4VTm+qWKvrAvmYMybZVokbp4Udco1mNwJrTNZPQ==",
             "dev": true
         },
+        "@types/har-format": {
+            "version": "1.2.4",
+            "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.4.tgz",
+            "integrity": "sha512-iUxzm1meBm3stxUMzRqgOVHjj4Kgpgu5w9fm4X7kPRfSgVRzythsucEN7/jtOo8SQzm+HfcxWWzJS0mJDH/3DQ=="
+        },
         "@types/jquery": {
             "version": "3.3.36",
             "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.36.tgz",
@@ -3253,6 +3280,15 @@
             "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
             "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
         },
+        "chrome": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/chrome/-/chrome-0.1.0.tgz",
+            "integrity": "sha1-9h2beS/v6MGUxwVt3BAscmqGQyk=",
+            "requires": {
+                "exeq": "^2.2.0",
+                "plist": "^1.1.0"
+            }
+        },
         "chrome-trace-event": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
@@ -5290,6 +5326,15 @@
             "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
             "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
         },
+        "exeq": {
+            "version": "2.4.0",
+            "resolved": "https://registry.npmjs.org/exeq/-/exeq-2.4.0.tgz",
+            "integrity": "sha1-Td8qaEZIxCeteZNJzzO9dTWPiEo=",
+            "requires": {
+                "bluebird": "^3.0.3",
+                "native-or-bluebird": "^1.2.0"
+            }
+        },
         "exif": {
             "version": "0.6.0",
             "resolved": "https://registry.npmjs.org/exif/-/exif-0.6.0.tgz",
@@ -8695,6 +8740,11 @@
             "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
             "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
         },
+        "native-or-bluebird": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/native-or-bluebird/-/native-or-bluebird-1.2.0.tgz",
+            "integrity": "sha1-OcR7/Xgl0fuf+tMiEK4l2q3xAck="
+        },
         "needle": {
             "version": "2.4.1",
             "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.1.tgz",
@@ -13260,6 +13310,24 @@
                 "semver-compare": "^1.0.0"
             }
         },
+        "plist": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/plist/-/plist-1.2.0.tgz",
+            "integrity": "sha1-CEtQk93JJQbiWfh0uNmxr7jHlZM=",
+            "requires": {
+                "base64-js": "0.0.8",
+                "util-deprecate": "1.0.2",
+                "xmlbuilder": "4.0.0",
+                "xmldom": "0.1.x"
+            },
+            "dependencies": {
+                "base64-js": {
+                    "version": "0.0.8",
+                    "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
+                    "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg="
+                }
+            }
+        },
         "pn": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
@@ -17816,12 +17884,32 @@
             "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
             "dev": true
         },
+        "xmlbuilder": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.0.0.tgz",
+            "integrity": "sha1-mLj2UcowqmJANvEn0RzGbce5B6M=",
+            "requires": {
+                "lodash": "^3.5.0"
+            },
+            "dependencies": {
+                "lodash": {
+                    "version": "3.10.1",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+                    "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
+                }
+            }
+        },
         "xmlchars": {
             "version": "2.2.0",
             "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
             "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
             "dev": true
         },
+        "xmldom": {
+            "version": "0.1.31",
+            "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
+            "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ=="
+        },
         "xmlhttprequest-ssl": {
             "version": "1.5.5",
             "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
diff --git a/package.json b/package.json
index ca82d523d..d1d7935af 100644
--- a/package.json
+++ b/package.json
@@ -117,6 +117,7 @@
         "@hig/flyout": "^1.2.0",
         "@hig/theme-context": "^2.1.3",
         "@hig/theme-data": "^2.13.0",
+        "@types/chrome": "0.0.114",
         "adm-zip": "^0.4.13",
         "archiver": "^3.1.1",
         "array-batcher": "^1.2.3",
@@ -128,6 +129,7 @@
         "bootstrap": "^4.4.1",
         "canvas": "^2.5.0",
         "child_process": "^1.0.2",
+        "chrome": "^0.1.0",
         "class-transformer": "^0.2.0",
         "color": "^3.1.2",
         "colors": "^1.4.0",
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index ab087335e..67f2f244c 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -126,13 +126,13 @@ export class DocumentManager {
         finished?.();
     }
     public jumpToDocument = async (
-        targetDoc: Doc,
-        willZoom: boolean,
-        createViewFunc = DocumentManager.addRightSplit,
-        docContext?: Doc,
-        linkId?: string,
-        closeContextIfNotFound: boolean = false,
-        originatingDoc: Opt<Doc> = undefined,
+        targetDoc: Doc,        // document to display
+        willZoom: boolean,     // whether to zoom doc to take up most of screen
+        createViewFunc = DocumentManager.addRightSplit, // how to create a view of the doc if it doesn't exist
+        docContext?: Doc,  // context to load that should contain the target
+        linkId?: string,   // link that's being followed
+        closeContextIfNotFound: boolean = false, // after opening a context where the document should be, this determines whether the context should be closed if the Doc isn't actually there
+        originatingDoc: Opt<Doc> = undefined, // doc that initiated the display of the target odoc
         finished?: () => void
     ): Promise<void> => {
         const getFirstDocView = DocumentManager.Instance.getFirstDocumentView;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index a0a6adab7..a1d1b0ece 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -51,6 +51,8 @@ import { PreviewCursor } from './PreviewCursor';
 import { ScriptField } from '../../fields/ScriptField';
 import { TimelineMenu } from './animationtimeline/TimelineMenu';
 import { SnappingManager } from '../util/SnappingManager';
+import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
+import { DocumentManager } from '../util/DocumentManager';
 
 @observer
 export class MainView extends React.Component {
@@ -83,6 +85,14 @@ export class MainView extends React.Component {
         window.removeEventListener("keydown", KeyManager.Instance.handle);
         window.addEventListener("keydown", KeyManager.Instance.handle);
         window.addEventListener("paste", KeyManager.Instance.paste as any);
+        document.addEventListener("dash", (e: any) => {  // event used by chrome plugin to tell Dash which document to focus on 
+            const id = FormattedTextBox.GetDocFromUrl(e.detail);
+            DocServer.GetRefField(id).then(doc => {
+                if (doc instanceof Doc) {
+                    DocumentManager.Instance.jumpToDocument(doc, false, undefined);
+                }
+            });
+        });
     }
 
     componentWillUnMount() {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 7a4ecfa9c..e245e045c 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -742,16 +742,16 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
         const more = cm.findByDescription("More...");
         const moreItems: ContextMenuProps[] = more && "subitems" in more ? more.subitems : [];
-        moreItems.push({ description: "Make Add Only", event: () => this.layoutDoc.ACL = this.dataDoc.ACL = "addOnly", icon: "concierge-bell" });
-        moreItems.push({ description: "Make Read Only", event: () => this.layoutDoc.ACL = this.dataDoc.ACL = "readOnly", icon: "concierge-bell" });
-        moreItems.push({ description: "Make Private", event: () => this.layoutDoc[AclSym] = this.dataDoc[AclSym] = "noAccess", icon: "concierge-bell" });
+        moreItems.push({ description: "Make Add Only", event: () => this.dataDoc.ACL = this.layoutDoc.ACL = "addOnly", icon: "concierge-bell" });
+        moreItems.push({ description: "Make Read Only", event: () => this.dataDoc.ACL = this.layoutDoc.ACL = "readOnly", icon: "concierge-bell" });
+        moreItems.push({ description: "Make Private", event: () => this.dataDoc.ACL = this.layoutDoc.ACL = "noAccess", icon: "concierge-bell" });
         moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" });
         moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" });
         moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" });
 
         if (!ClientUtils.RELEASE) {
             // let copies: ContextMenuProps[] = [];
-            moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]), icon: "fingerprint" });
+            moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" });
             // cm.addItem({ description: "Copy...", subitems: copies, icon: "copy" });
         }
         if (Cast(Doc.GetProto(this.props.Document).data, listSpec(Doc))) {
-- 
cgit v1.2.3-70-g09d2


From 9588e56079f7e4ab98da1849f44996656649bc06 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 3 Jun 2020 13:37:22 -0400
Subject: fixes for acl's (naming, ignore owner)

---
 src/client/documents/Documents.ts       |  1 +
 src/client/views/nodes/DocumentView.tsx | 18 +++++++++++++++---
 src/fields/Doc.ts                       | 25 +++++++++++++++----------
 3 files changed, 31 insertions(+), 13 deletions(-)

(limited to 'src/client/views/nodes/DocumentView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index f7e19eecd..1a1d5c59e 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -514,6 +514,7 @@ export namespace Docs {
             const dataDoc = MakeDataDelegate(proto, protoProps, data, fieldKey);
             const viewDoc = Doc.MakeDelegate(dataDoc, delegId);
 
+            viewDoc.author = Doc.CurrentUserEmail;
             viewDoc.type !== DocumentType.LINK && DocUtils.MakeLinkToActiveAudio(viewDoc);
 
             return Doc.assign(viewDoc, delegateProps, true);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index e245e045c..d132f0b3b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -44,6 +44,7 @@ import "./DocumentView.scss";
 import { LinkAnchorBox } from './LinkAnchorBox';
 import { RadialMenu } from './RadialMenu';
 import React = require("react");
+import { undo } from 'prosemirror-history';
 
 library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight,
     fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale,
@@ -682,6 +683,17 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         this.Document.lockedPosition = this.Document.lockedPosition ? undefined : true;
     }
 
+    @undoBatch
+    @action
+    setAcl = (acl: "readOnly" | "addOnly" | "ownerOnly") => {
+        this.layoutDoc.ACL = this.dataDoc.ACL = acl;
+        DocListCast(this.dataDoc[Doc.LayoutFieldKey(this.dataDoc)]).map(d => {
+            if (d.author === Doc.CurrentUserEmail) d.ACL = acl;
+            const data = d[DataSym];
+            if (data && data.author === Doc.CurrentUserEmail) data.ACL = acl;
+        });
+    }
+
     @action
     onContextMenu = async (e: React.MouseEvent | Touch): Promise<void> => {
         // the touch onContextMenu is button 0, the pointer onContextMenu is button 2
@@ -742,9 +754,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
         const more = cm.findByDescription("More...");
         const moreItems: ContextMenuProps[] = more && "subitems" in more ? more.subitems : [];
-        moreItems.push({ description: "Make Add Only", event: () => this.dataDoc.ACL = this.layoutDoc.ACL = "addOnly", icon: "concierge-bell" });
-        moreItems.push({ description: "Make Read Only", event: () => this.dataDoc.ACL = this.layoutDoc.ACL = "readOnly", icon: "concierge-bell" });
-        moreItems.push({ description: "Make Private", event: () => this.dataDoc.ACL = this.layoutDoc.ACL = "noAccess", icon: "concierge-bell" });
+        moreItems.push({ description: "Make Add Only", event: () => this.setAcl("addOnly"), icon: "concierge-bell" });
+        moreItems.push({ description: "Make Read Only", event: () => this.setAcl("readOnly"), icon: "concierge-bell" });
+        moreItems.push({ description: "Make Private", event: () => this.setAcl("ownerOnly"), icon: "concierge-bell" });
         moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" });
         moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" });
         moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" });
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 6891bf652..e46acd16d 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -94,7 +94,7 @@ export const HeightSym = Symbol("Height");
 export const DataSym = Symbol("Data");
 export const LayoutSym = Symbol("Layout");
 export const AclSym = Symbol("Acl");
-export const AclPrivate = Symbol("AclNoAccess");
+export const AclPrivate = Symbol("AclOwnerOnly");
 export const AclReadonly = Symbol("AclReadOnly");
 export const AclAddonly = Symbol("AclAddonly");
 export const UpdatingFromServer = Symbol("UpdatingFromServer");
@@ -103,13 +103,17 @@ const CachedUpdates = Symbol("Cached updates");
 
 function fetchProto(doc: Doc) {
     if (doc.author !== Doc.CurrentUserEmail) {
-        if (doc.ACL === "noAccess") {
-            doc[AclSym] = AclPrivate;
-            return undefined;
-        } else if (doc.ACL === "readOnly") {
-            doc[AclSym] = AclReadonly;
-        } else if (doc.ACL === "addOnly") {
-            doc[AclSym] = AclAddonly;
+        const acl = Doc.Get(doc, "ACL", true);
+        switch (acl) {
+            case "ownerOnly":
+                doc[AclSym] = AclPrivate;
+                return undefined;
+            case "readOnly":
+                doc[AclSym] = AclReadonly;
+                break;
+            case "addOnly":
+                doc[AclSym] = AclAddonly;
+                break;
         }
     }
 
@@ -117,7 +121,7 @@ function fetchProto(doc: Doc) {
     if (proto instanceof Promise) {
         proto.then(proto => {
             if (proto.author !== Doc.CurrentUserEmail) {
-                if (proto.ACL === "noAccess") {
+                if (proto.ACL === "ownerOnly") {
                     proto[AclSym] = doc[AclSym] = AclPrivate;
                     return undefined;
                 } else if (proto.ACL === "readOnly") {
@@ -484,6 +488,7 @@ export namespace Doc {
         }
         alias.aliasOf = doc;
         alias.title = ComputedField.MakeFunction(`renameAlias(this, ${Doc.GetProto(doc).aliasNumber = NumCast(Doc.GetProto(doc).aliasNumber) + 1})`);
+        alias.author = Doc.CurrentUserEmail;
         return alias;
     }
 
@@ -614,7 +619,7 @@ export namespace Doc {
                 }
             }
         });
-
+        copy["author"] = Doc.CurrentUserEmail;
         return copy;
     }
 
-- 
cgit v1.2.3-70-g09d2

