From 872d9a57bdb5bf2b3f3a26acf17d77b72dcb5164 Mon Sep 17 00:00:00 2001
From: Jude <julie_wang1@brown.edu>
Date: Sat, 9 Mar 2019 20:09:11 -0500
Subject: schema view improvements

---
 src/client/views/collections/CollectionSchemaView.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 49f95c014..19ed97391 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -24,7 +24,7 @@ import { setupDrag } from "../../util/DragManager";
 @observer
 export class CollectionSchemaView extends CollectionViewBase {
     private _mainCont = React.createRef<HTMLDivElement>();
-    private DIVIDER_WIDTH = 5;
+    private DIVIDER_WIDTH = 4;
 
     @observable _contentScaling = 1; // used to transfer the dimensions of the content pane in the DOM to the ContentScaling prop of the DocumentView
     @observable _dividerX = 0;
-- 
cgit v1.2.3-70-g09d2


From 81c0a8373fd5cb051531762243e200f11f8c7297 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <abdullah_ahmed@brown.edu>
Date: Sat, 9 Mar 2019 23:00:41 -0500
Subject: editable workspace titles now supported, added 'display' prop to
 EditableView

---
 src/client/views/EditableView.tsx                  |  5 ++--
 .../views/collections/CollectionSchemaView.tsx     |  6 ++--
 .../views/collections/CollectionTreeView.tsx       |  5 +++-
 .../authentication/controllers/WorkspacesMenu.tsx  | 32 +++++++++++++++-------
 4 files changed, 33 insertions(+), 15 deletions(-)

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

diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 84b1b91c3..55a49863d 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -20,6 +20,7 @@ export interface EditableProps {
      */
     contents: any;
     height: number
+    display: string;
 }
 
 /**
@@ -46,10 +47,10 @@ export class EditableView extends React.Component<EditableProps> {
     render() {
         if (this.editing) {
             return <input defaultValue={this.props.GetValue()} onKeyDown={this.onKeyDown} autoFocus onBlur={action(() => this.editing = false)}
-                style={{ display: "inline" }}></input>
+                style={{ display: this.props.display }}></input>
         } else {
             return (
-                <div className="editableView-container-editing" style={{ display: "inline", height: "100%", maxHeight: `${this.props.height}` }}
+                <div className="editableView-container-editing" style={{ display: this.props.display, height: "100%", maxHeight: `${this.props.height}` }}
                     onClick={action(() => this.editing = true)}>
                     {this.props.contents}
                 </div>
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 49f95c014..2868e1322 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -50,7 +50,9 @@ export class CollectionSchemaView extends CollectionViewBase {
         let onItemDown = setupDrag(reference, () => props.doc);
         return (
             <div onPointerDown={onItemDown} key={props.doc.Id} ref={reference}>
-                <EditableView contents={contents}
+                <EditableView
+                    display={"inline"}
+                    contents={contents}
                     height={36} GetValue={() => {
                         let field = props.doc.Get(props.fieldKey);
                         if (field && field instanceof Field) {
@@ -59,7 +61,7 @@ export class CollectionSchemaView extends CollectionViewBase {
                         return field || "";
                     }}
                     SetValue={(value: string) => {
-                        let script = CompileScript(value, undefined, true);
+                        let script = CompileScript(value);
                         if (!script.compiled) {
                             return false;
                         }
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 8b06d9ac4..9c31bdae2 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -69,7 +69,9 @@ class TreeView extends React.Component<TreeViewProps> {
             return <div key={this.props.document.Id}></div>;
         }
 
-        return <div className="docContainer"> <EditableView contents={title.Data}
+        return <div className="docContainer"> <EditableView
+            display={"inline"}
+            contents={title.Data}
             height={36} GetValue={() => {
                 let title = this.props.document.GetT<TextField>(KeyStore.Title, TextField);
                 if (title && title !== "<Waiting>")
@@ -159,6 +161,7 @@ export class CollectionTreeView extends CollectionViewBase {
             <div id="body" className="collectionTreeView-dropTarget" onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }}>
                 <h3>
                     <EditableView contents={titleStr}
+                        display={"inline"}
                         height={72} GetValue={() => {
                             return this.props.Document.Title;
                         }} SetValue={(value: string) => {
diff --git a/src/server/authentication/controllers/WorkspacesMenu.tsx b/src/server/authentication/controllers/WorkspacesMenu.tsx
index 70c37774c..ffef2e11c 100644
--- a/src/server/authentication/controllers/WorkspacesMenu.tsx
+++ b/src/server/authentication/controllers/WorkspacesMenu.tsx
@@ -7,6 +7,8 @@ import './WorkspacesMenu.css'
 import { Document } from '../../../fields/Document';
 import { Server } from '../../../client/Server';
 import { Field } from '../../../fields/Field';
+import { EditableView } from '../../../client/views/EditableView';
+import { KeyStore } from '../../../fields/KeyStore';
 
 export interface WorkspaceMenuProps {
     active: Document;
@@ -67,19 +69,29 @@ export class WorkspacesMenu extends React.Component<WorkspaceMenuProps> {
                     }}
                     onClick={this.addNewWorkspace}
                 />
-                {this.props.allWorkspaces.map(s =>
-                    <li className={"ids"}
+                {this.props.allWorkspaces.map((s, i) =>
+                    <div
                         key={s.Id}
-                        style={{
-                            listStyleType: "none",
-                            color: s.Id === this.props.active.Id ? "darkblue" : "black",
-                            cursor: "grab"
-                        }}
-                        onClick={() => {
+                        onContextMenu={(e) => {
+                            e.preventDefault();
                             this.props.open(s);
-                            console.log(this.props.allWorkspaces.length);
                         }}
-                    >{s.Title}</li>
+                        style={{
+                            marginTop: 10
+                        }}
+                    >
+                        <span>{i + 1} - </span>
+                        <EditableView
+                            display={"inline"}
+                            GetValue={() => { return s.Title }}
+                            SetValue={(title: string): boolean => {
+                                s.SetText(KeyStore.Title, title);
+                                return true;
+                            }}
+                            contents={s.Title}
+                            height={20}
+                        />
+                    </div>
                 )}
             </div>
         );
-- 
cgit v1.2.3-70-g09d2


From 43c96800f0a651247fdcaf2c77c710a30cb3f79d Mon Sep 17 00:00:00 2001
From: Jude <julie_wang1@brown.edu>
Date: Sun, 10 Mar 2019 13:06:04 -0400
Subject: changed default sizing

---
 src/client/documents/Documents.ts                  |  8 +++---
 src/client/views/Main.tsx                          | 14 ++++-----
 src/client/views/_global_variables.scss            |  2 +-
 .../views/collections/CollectionFreeFormView.scss  |  2 +-
 .../views/collections/CollectionSchemaView.scss    |  2 ++
 .../views/collections/CollectionSchemaView.tsx     |  2 +-
 .../views/collections/CollectionTreeView.scss      | 33 ++++++++++++----------
 src/client/views/nodes/FormattedTextBox.tsx        |  2 +-
 src/client/views/nodes/ImageBox.scss               | 29 +++++++++----------
 9 files changed, 49 insertions(+), 45 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index fc210e9a2..30a292502 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -113,7 +113,7 @@ export namespace Documents {
     function GetCollectionPrototype(): Document {
         return collProto ? collProto :
             collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("DataKey"),
-                { panx: 0, pany: 0, scale: 1, layoutKeys: [KeyStore.Data] });
+                { panx: 0, pany: 0, scale: 1, width: 500, height: 500, layoutKeys: [KeyStore.Data] });
     }
 
     function GetKVPPrototype(): Document {
@@ -125,9 +125,9 @@ export namespace Documents {
     export function ImageDocument(url: string, options: DocumentOptions = {}) {
         let doc = SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] },
             new URL(url), ImageField);
-        doc.SetText(KeyStore.Caption, "my caption...");
-        doc.SetText(KeyStore.BackgroundLayout, EmbeddedCaption());
-        doc.SetText(KeyStore.OverlayLayout, FixedCaption());
+        // doc.SetText(KeyStore.Caption, "my caption...");
+        // doc.SetText(KeyStore.BackgroundLayout, EmbeddedCaption());
+        // doc.SetText(KeyStore.OverlayLayout, FixedCaption());
         return doc;
     }
     export function TextDocument(options: DocumentOptions = {}) {
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 1caaa1cba..79c5cb5aa 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -76,12 +76,12 @@ Documents.initProtos(mainDocId, (res?: Document) => {
     let pdfurl = "http://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf"
     let weburl = "https://cs.brown.edu/courses/cs166/";
     let clearDatabase = action(() => Utils.Emit(Server.Socket, MessageStore.DeleteAll, {}))
-    let addTextNode = action(() => Documents.TextDocument({ width: 200, height: 200, title: "a text note" }))
-    let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, title: "a freeform collection" }));
-    let addSchemaNode = action(() => Documents.SchemaDocument([Documents.TextDocument()], { width: 200, height: 200, title: "a schema collection" }));
-    let addPDFNode = action(() => Documents.PdfDocument(pdfurl, { width: 200, height: 200, title: "a schema collection" }));
+    let addTextNode = action(() => Documents.TextDocument({ width: 230, height: 130, title: "a text note" }))
+    let addColNode = action(() => Documents.FreeformDocument([], { width: 300, height: 300, title: "a freeform collection" }));
+    let addSchemaNode = action(() => Documents.SchemaDocument([Documents.TextDocument()], { width: 450, height: 200, title: "a schema collection" }));
+    let addPDFNode = action(() => Documents.PdfDocument(pdfurl, { width: 300, height: 400, title: "a pdf" }));
     let addImageNode = action(() => Documents.ImageDocument(imgurl, { width: 200, height: 200, title: "an image of a cat" }));
-    let addWebNode = action(() => Documents.WebDocument(weburl, { width: 200, height: 200, title: "a sample web page" }));
+    let addWebNode = action(() => Documents.WebDocument(weburl, { width: 300, height: 400, title: "a sample web page" }));
 
 
     let addClick = (creator: () => Document) => action(() =>
@@ -100,7 +100,7 @@ Documents.initProtos(mainDocId, (res?: Document) => {
 
     ReactDOM.render((
         <div style={{ position: "absolute", width: "100%", height: "100%" }}>
-            <div id="dash-title">— DASH —</div>
+            {/* <div id="dash-title">— DASH —</div> */}
 
             <DocumentView Document={mainContainer}
                 AddDocument={undefined} RemoveDocument={undefined} ScreenToLocalTransform={() => Transform.Identity}
@@ -153,7 +153,7 @@ Documents.initProtos(mainDocId, (res?: Document) => {
 
             </div>
 
-            <InkingControl />
+            {/* <InkingControl /> */}
         </div >),
         document.getElementById('root'));
 })
diff --git a/src/client/views/_global_variables.scss b/src/client/views/_global_variables.scss
index 333fb3122..1c06ab44a 100644
--- a/src/client/views/_global_variables.scss
+++ b/src/client/views/_global_variables.scss
@@ -1,4 +1,4 @@
-@import url("https://fonts.googleapis.com/css?family=Roboto+Slab:300,700|Crimson+Text:400,400i,700");
+@import url("https://fonts.googleapis.com/css?family=Roboto+Slab:,700|Crimson+Text:400,400i,700");
 
 // colors
 $light-color: #fcfbf7;
diff --git a/src/client/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss
index 90caa0d14..7250c9241 100644
--- a/src/client/views/collections/CollectionFreeFormView.scss
+++ b/src/client/views/collections/CollectionFreeFormView.scss
@@ -41,7 +41,7 @@
     background: $light-color-secondary;
   }
 
-  border: 0px solid $intermediate-color;
+  border: 0px solid transparent;
   border-radius: $border-radius;
   box-sizing: border-box;
   position: absolute;
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index cb0040657..b66fc7981 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -7,6 +7,8 @@
   position: absolute;
   width: 100%;
   height: 100%;
+  overflow: hidden;
+
   .collectionSchemaView-previewRegion {
     position: relative;
     background: $light-color;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 19ed97391..deb307fb3 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -31,7 +31,7 @@ export class CollectionSchemaView extends CollectionViewBase {
     @observable _panelWidth = 0;
     @observable _panelHeight = 0;
     @observable _selectedIndex = 0;
-    @observable _splitPercentage: number = 50;
+    @observable _splitPercentage: number = 100;
 
     renderCell = (rowProps: CellInfo) => {
         let props: FieldViewProps = {
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index f8d580a7b..4b28ded45 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -1,37 +1,40 @@
+@import "../global_variables";
+
 #body {
-    padding: 20px;
-    background: #bbbbbb;
+  padding: 20px;
+  background: $light-color-secondary;
 }
 
 ul {
-    list-style: none;
+  list-style: none;
 }
 
 li {
-    margin: 5px 0;
+  margin: 5px 0;
 }
 
 .no-indent {
-    padding-left: 0;
+  padding-left: 0;
 }
 
 .bullet {
-    width: 1.5em;
-    display: inline-block;
+  width: 1.5em;
+  display: inline-block;
 }
 
 .collectionTreeView-dropTarget {
-    border-style: solid;
-    box-sizing: border-box;
-    height: 100%;
+  border: 0px solid $intermediate-color;
+  border-radius: $border-radius;
+  box-sizing: border-box;
+  height: 100%;
 }
 
 .docContainer {
-    display: inline-table;
+  display: inline-table;
 }
 
 .delete-button {
-    color: #999999;
-    float: right;
-    margin-left: 1em;
-}
\ No newline at end of file
+  color: $intermediate-color;
+  float: right;
+  margin-left: 1em;
+}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index a6cee9957..a375cfc48 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -31,7 +31,7 @@ import { ContextMenu } from "../../views/ContextMenu";
 //    and 'doc' property to the document that is being rendered
 //
 //  When rendered() by React, this extracts the TextController from the Document stored at the 
-//  specified Key and assigns it to an HTML input node.  When changes are made tot his node, 
+//  specified Key and assigns it to an HTML input node.  When changes are made to this node, 
 //  this will edit the document and assign the new value to that field.
 //]
 export class FormattedTextBox extends React.Component<FieldViewProps> {
diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss
index ea459b911..2cb460eea 100644
--- a/src/client/views/nodes/ImageBox.scss
+++ b/src/client/views/nodes/ImageBox.scss
@@ -1,22 +1,21 @@
-
 .imageBox-cont {
-    padding: 0vw;
-    position: relative;
-    text-align: center;
-    width: 100%;
-    height: auto;
-    max-width: 100%;
-    max-height: 100%
+  padding: 0vw;
+  position: relative;
+  text-align: center;
+  width: 100%;
+  height: auto;
+  max-width: 100%;
+  max-height: 100%;
 }
 
 .imageBox-cont img {
-    object-fit: contain;
-    height: 100%;
+  object-fit: contain;
+  height: 100%;
 }
 
 .imageBox-button {
-    padding : 0vw;
-    border: none;
-    width : 100%;
-    height: 100%;
-}
\ No newline at end of file
+  padding: 0vw;
+  border: none;
+  width: 100%;
+  height: 100%;
+}
-- 
cgit v1.2.3-70-g09d2


From 3874dd9ea6efb96f01c32827d2d2fc103d66d57b Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 11 Mar 2019 12:29:13 -0400
Subject: minor fix to divider dragger

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

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

diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 49f95c014..04f017378 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -203,6 +203,8 @@ export class CollectionSchemaView extends CollectionViewBase {
         )
         let previewHandle = !this.props.active() ? (null) : (
             <div className="collectionSchemaView-previewHandle" onPointerDown={this.onExpanderDown} />);
+        let dividerDragger = this._splitPercentage == 100 ? (null) :
+            <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
                 <div className="collectionSchemaView-dropTarget" onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}>
@@ -232,7 +234,7 @@ export class CollectionSchemaView extends CollectionViewBase {
                             </div>
                         }
                     </Measure>
-                    <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />
+                    {dividerDragger}
                     <div className="collectionSchemaView-previewRegion" style={{ width: `calc(${100 - this._splitPercentage}% - ${this.DIVIDER_WIDTH}px)` }}>
                         {content}
                     </div>
-- 
cgit v1.2.3-70-g09d2


From 44d669b46616e561aef874471d2740a4f205d9f0 Mon Sep 17 00:00:00 2001
From: Fawn <fangrui_tong@brown.edu>
Date: Mon, 11 Mar 2019 21:25:13 -0400
Subject: column adding works, but render doesn't get called on add

---
 .../views/collections/CollectionSchemaView.scss    | 91 +++++++++++++++-------
 .../views/collections/CollectionSchemaView.tsx     | 42 +++++++++-
 src/fields/Document.ts                             |  5 ++
 3 files changed, 108 insertions(+), 30 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index d40e6d314..38da3505e 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -1,5 +1,3 @@
-
-
 .collectionSchemaView-container {
     border-style: solid;
     box-sizing: border-box;
@@ -7,36 +5,74 @@
     width: 100%;
     height: 100%;
     .collectionSchemaView-previewRegion {
-        position: relative; 
-        background: black; 
-        float: left; 
+        position: relative;
+        background: black;
+        float: left;
         height: 100%;
     }
     .collectionSchemaView-previewHandle {
         position: absolute;
         height: 37px;
-        width: 20px; 
-        z-index: 20; 
-        right: 0; 
-        top: 0; 
-        background: Black ;
-    }
-    .collectionSchemaView-dividerDragger{
-        position: relative; 
-        background: black; 
-        float: left; 
+        width: 20px;
+        z-index: 20;
+        right: 0;
+        top: 0;
+        background: Black;
+    }
+    .collectionSchemaView-dividerDragger {
+        position: relative;
+        background: black;
+        float: left;
         height: 100%;
     }
     .collectionSchemaView-tableContainer {
         position: relative;
         float: left;
-        height: 100%; 
+        height: 100%;
     }
-
-    .ReactTable {
+    .collectionSchemaView-addColumn {
         position: absolute;
-       // display: inline-block;
-       // overflow: auto;
+        z-index: 20px;
+        right: 10px;
+        bottom: 10px;
+        input {
+            display: none;
+        }
+        label {
+            background: red;
+            display: inline-block;
+            border-radius: 18px;
+            font-size: 25px;
+            width: 36px;
+            height: 36px;
+            margin-right: 10px;
+            text-align: center;
+            cursor: pointer;
+        }
+        input:not(:checked)~.addColumn-options {
+            display: none;
+        }
+        .addColumn-options {
+            position: absolute;
+            right: 70px;
+            bottom: 0;
+            width: 150px;
+            background-color: white;
+            ul {
+                padding: 0;
+                margin: 0;
+            }
+            li {
+                padding: 6px;
+                border: 1px solid gray;
+                width: 100%;
+                margin: 0;
+            }
+        }
+    }
+    .ReactTable {
+        position: absolute; // display: inline-block;
+        // overflow: auto;
         width: 100%;
         height: 100%;
         background: white;
@@ -45,10 +81,8 @@
             overflow-y: auto;
             overflow-x: auto;
             height: 100%;
-
             display: -webkit-inline-box;
-            direction: ltr;
-            // direction:rtl;
+            direction: ltr; // direction:rtl;
             // display:block;
         }
         .rt-tbody {
@@ -63,8 +97,8 @@
             border-width: 1;
             border-right-color: #aaa;
             .imageBox-cont {
-                position:relative;
-                max-height:100%;
+                position: relative;
+                max-height: 100%;
             }
             .imageBox-cont img {
                 object-fit: contain;
@@ -78,9 +112,10 @@
         }
     }
     .ReactTable .rt-thead.-header {
-            background:grey;
-        }
-    .ReactTable .rt-th, .ReactTable .rt-td {
+        background: grey;
+    }
+    .ReactTable .rt-th,
+    .ReactTable .rt-td {
         max-height: 44;
         padding: 3px 7px;
     }
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 04f017378..e1036e9b0 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,5 +1,5 @@
 import React = require("react")
-import { action, observable } from "mobx";
+import { action, observable, ObservableMap, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import Measure from "react-measure";
 import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
@@ -17,6 +17,8 @@ import "./CollectionSchemaView.scss";
 import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
 import { CollectionViewBase } from "./CollectionViewBase";
 import { setupDrag } from "../../util/DragManager";
+import { Key } from "./../../../fields/Key";
+
 
 // bcz: need to add drag and drop of rows and columns.  This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
 
@@ -26,6 +28,7 @@ export class CollectionSchemaView extends CollectionViewBase {
     private _mainCont = React.createRef<HTMLDivElement>();
     private DIVIDER_WIDTH = 5;
 
+    @observable _columns: Array<Key> = [KeyStore.Title, KeyStore.Data, KeyStore.Author];
     @observable _contentScaling = 1; // used to transfer the dimensions of the content pane in the DOM to the ContentScaling prop of the DocumentView
     @observable _dividerX = 0;
     @observable _panelWidth = 0;
@@ -102,6 +105,29 @@ export class CollectionSchemaView extends CollectionViewBase {
         };
     }
 
+    @action
+    addColumn = (k: Key): void => {
+        this._columns.push(k);
+        console.log("adding", this._columns.length);
+    }
+
+    findAllDocumentKeys = (docs: Array<Document>): Set<Key> => {
+        let keys = new Set();
+        docs.forEach(doc => {
+            let fields: ObservableMap<string, { key: Key, field: Field }> = doc.Fields;
+            Array.from(fields).map(item => {
+                let v: { key: Key, field: Field } = item[1];
+                let k = v.key;
+                keys.add(k);
+            })
+        })
+        keys.delete(KeyStore.Title);
+        keys.delete(KeyStore.Data);
+        keys.delete(KeyStore.Author);
+        console.log("key set", keys);
+        return keys;
+    }
+
     _startSplitPercent = 0;
     @action
     onDividerMove = (e: PointerEvent): void => {
@@ -179,7 +205,7 @@ export class CollectionSchemaView extends CollectionViewBase {
     focusDocument = (doc: Document) => { }
 
     render() {
-        const columns = this.props.Document.GetList(KeyStore.ColumnsKey, [KeyStore.Title, KeyStore.Data, KeyStore.Author])
+        const columns = this.props.Document.GetList(KeyStore.ColumnsKey, this._columns)
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
         const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined;
         let content = this._selectedIndex == -1 || !selected ? (null) : (
@@ -205,6 +231,7 @@ export class CollectionSchemaView extends CollectionViewBase {
             <div className="collectionSchemaView-previewHandle" onPointerDown={this.onExpanderDown} />);
         let dividerDragger = this._splitPercentage == 100 ? (null) :
             <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />
+
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
                 <div className="collectionSchemaView-dropTarget" onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}>
@@ -231,6 +258,16 @@ export class CollectionSchemaView extends CollectionViewBase {
                                     }}
                                     getTrProps={this.getTrProps}
                                 />
+                                <div className="collectionSchemaView-addColumn" >
+                                    <input type="checkbox" id="addColumn-toggle" />
+                                    <label htmlFor="addColumn-toggle" title="Add Column"><p>+</p></label>
+
+                                    <div className="addColumn-options">
+                                        <ul>{Array.from(this.findAllDocumentKeys(children)).map(item => {
+                                            return <li onClick={() => this.addColumn(item)}>{item.Name}</li>
+                                        })}</ul>
+                                    </div>
+                                </div>
                             </div>
                         }
                     </Measure>
@@ -239,6 +276,7 @@ export class CollectionSchemaView extends CollectionViewBase {
                         {content}
                     </div>
                     {previewHandle}
+
                 </div>
             </div >
         )
diff --git a/src/fields/Document.ts b/src/fields/Document.ts
index 25e239417..6cf9c194e 100644
--- a/src/fields/Document.ts
+++ b/src/fields/Document.ts
@@ -38,6 +38,11 @@ export class Document extends Field {
         return this.GetText(KeyStore.Title, "<untitled>");
     }
 
+    @computed
+    public get Fields() {
+        return this.fields;
+    }
+
     /**
      * Get the field in the document associated with the given key. If the
      * associated field has not yet been filled in from the server, a request
-- 
cgit v1.2.3-70-g09d2


From c17605b4d1fe04429b029ff5a161f31ce19f5fd4 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 15 Mar 2019 10:48:23 -0400
Subject: think video resizing is fixed now.

---
 src/client/views/collections/CollectionSchemaView.tsx | 2 +-
 src/client/views/nodes/VideoBox.tsx                   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 37620cd7c..14e1df8ca 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -49,7 +49,7 @@ export class CollectionSchemaView extends CollectionViewBase {
         let reference = React.createRef<HTMLDivElement>();
         let onItemDown = setupDrag(reference, () => props.doc);
         return (
-            <div onPointerDown={onItemDown} key={props.doc.Id} ref={reference}>
+            <div className="collectionSchemaView-cellContents" onPointerDown={onItemDown} style={{ height: "36px" }} key={props.doc.Id} ref={reference}>
                 <EditableView contents={contents}
                     height={36} GetValue={() => {
                         let field = props.doc.Get(props.fieldKey);
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 053d9dd56..fef278cec 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -30,7 +30,7 @@ export class VideoBox extends React.Component<FieldViewProps> {
             var nativeWidth = this.props.doc.GetNumber(KeyStore.NativeWidth, 0);
             var nativeHeight = this.props.doc.GetNumber(KeyStore.NativeHeight, 0);
             var newNativeHeight = nativeWidth * r.entry.height / r.entry.width;
-            if (newNativeHeight != nativeHeight && !isNaN(newNativeHeight)) {
+            if (!nativeHeight && newNativeHeight != nativeHeight && !isNaN(newNativeHeight)) {
                 this.props.doc.SetNumber(KeyStore.Height, newNativeHeight / nativeWidth * this.props.doc.GetNumber(KeyStore.Width, 0));
                 this.props.doc.SetNumber(KeyStore.NativeHeight, newNativeHeight);
             }
@@ -48,7 +48,7 @@ export class VideoBox extends React.Component<FieldViewProps> {
 
         //setTimeout(action(() => this._loaded = true), 500);
         return (
-            <div style={{ width: "100%", height: "Auto" }} >
+            <div style={{ width: "100%", height: "100%" }} >
                 <Measure onResize={this.setScaling}>
                     {({ measureRef }) =>
                         <video className="videobox-cont" ref={measureRef}>
-- 
cgit v1.2.3-70-g09d2


From 487a74d28501cbdc86f0d02fef656754ed22ae19 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 15 Mar 2019 13:30:22 -0400
Subject: fixed various issues with schema/videos

---
 src/client/views/EditableView.tsx                  |  2 +-
 .../views/collections/CollectionFreeFormView.tsx   |  6 ++---
 .../views/collections/CollectionSchemaView.scss    |  2 +-
 .../views/collections/CollectionSchemaView.tsx     | 28 ++++++++++++----------
 src/client/views/collections/MarqueeView.tsx       |  2 +-
 src/client/views/nodes/VideoBox.tsx                | 16 ++++++-------
 src/fields/KeyStore.ts                             |  1 +
 7 files changed, 28 insertions(+), 29 deletions(-)

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

diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 757bfeae6..3b54c0dbb 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -50,7 +50,7 @@ export class EditableView extends React.Component<EditableProps> {
                 style={{ display: "inline" }}></input>
         } else {
             return (
-                <div className="editableView-container-editing" style={{ display: "inline", height: "100%", maxHeight: `${this.props.height}` }}
+                <div className="editableView-container-editing" style={{ display: "inline", height: "auto", maxHeight: `${this.props.height}` }}
                     onClick={action(() => this.editing = true)}>
                     {this.props.contents}
                 </div>
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index c8b745254..a94539312 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -126,7 +126,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
     onPointerUp = (e: PointerEvent): void => {
         e.stopPropagation();
 
-        if (!this.MarqueeVisible && Math.abs(this.DownX - e.clientX) < 3 && Math.abs(this.DownY - e.clientY) < 3) {
+        if (Math.abs(this.DownX - e.clientX) < 4 && Math.abs(this.DownY - e.clientY) < 4) {
             //show preview text cursor on tap
             this.PreviewCursorVisible = true;
             //select is not already selected
@@ -140,9 +140,8 @@ export class CollectionFreeFormView extends CollectionViewBase {
     @action
     onPointerMove = (e: PointerEvent): void => {
         if (!e.cancelBubble && this.props.active()) {
-            if (e.buttons != 2 && !e.altKey && !e.metaKey && !this.MarqueeVisible) {
+            if (e.buttons == 1 && !e.altKey && !e.metaKey) {
                 this.MarqueeVisible = true;
-                this.PreviewCursorVisible = false;
             }
             if (this.MarqueeVisible) {
                 e.stopPropagation();
@@ -152,7 +151,6 @@ export class CollectionFreeFormView extends CollectionViewBase {
                 let x = this.props.Document.GetNumber(KeyStore.PanX, 0);
                 let y = this.props.Document.GetNumber(KeyStore.PanY, 0);
                 let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
-                this.PreviewCursorVisible = false;
                 this.SetPan(x - dx, y - dy);
                 this._lastX = e.pageX;
                 this._lastY = e.pageY;
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index fdcad1355..0d615dc01 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -84,7 +84,7 @@
       }
       .videobox-cont  {
         object-fit: contain;
-        max-width: 100%;
+        width:auto;
         height: 100%;
       }
     }
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 14e1df8ca..8c1aeef2c 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,5 +1,5 @@
 import React = require("react")
-import { action, observable } from "mobx";
+import { action, observable, computed } from "mobx";
 import { observer } from "mobx-react";
 import Measure from "react-measure";
 import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
@@ -31,7 +31,7 @@ export class CollectionSchemaView extends CollectionViewBase {
     @observable _panelWidth = 0;
     @observable _panelHeight = 0;
     @observable _selectedIndex = 0;
-    @observable _splitPercentage: number = 100;
+    @computed get splitPercentage() { return this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0); }
 
     renderCell = (rowProps: CellInfo) => {
         let props: FieldViewProps = {
@@ -89,7 +89,8 @@ export class CollectionSchemaView extends CollectionViewBase {
         return {
             onClick: action((e: React.MouseEvent, handleOriginal: Function) => {
                 that._selectedIndex = rowInfo.index;
-                this._splitPercentage += 0.05; // bcz - ugh - needed to force Measure to do its thing and call onResize
+                // bcz - ugh - needed to force Measure to do its thing and call onResize
+                this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage - 0.05)
 
                 if (handleOriginal) {
                     handleOriginal()
@@ -106,18 +107,18 @@ export class CollectionSchemaView extends CollectionViewBase {
     @action
     onDividerMove = (e: PointerEvent): void => {
         let nativeWidth = this._mainCont.current!.getBoundingClientRect();
-        this._splitPercentage = Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100);
+        this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, 100 - Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100));
     }
     @action
     onDividerUp = (e: PointerEvent): void => {
         document.removeEventListener("pointermove", this.onDividerMove);
         document.removeEventListener('pointerup', this.onDividerUp);
-        if (this._startSplitPercent == this._splitPercentage) {
-            this._splitPercentage = this._splitPercentage == 1 ? 66 : 100;
+        if (this._startSplitPercent == this.splitPercentage) {
+            this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0);
         }
     }
     onDividerDown = (e: React.PointerEvent) => {
-        this._startSplitPercent = this._splitPercentage;
+        this._startSplitPercent = this.splitPercentage;
         e.stopPropagation();
         e.preventDefault();
         document.addEventListener("pointermove", this.onDividerMove);
@@ -134,12 +135,12 @@ export class CollectionSchemaView extends CollectionViewBase {
         e.preventDefault();
         document.removeEventListener("pointermove", this.onExpanderMove);
         document.removeEventListener('pointerup', this.onExpanderUp);
-        if (this._startSplitPercent == this._splitPercentage) {
-            this._splitPercentage = this._splitPercentage == 100 ? 66 : 100;
+        if (this._startSplitPercent == this.splitPercentage) {
+            this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0);
         }
     }
     onExpanderDown = (e: React.PointerEvent) => {
-        this._startSplitPercent = this._splitPercentage;
+        this._startSplitPercent = this.splitPercentage;
         e.stopPropagation();
         e.preventDefault();
         document.addEventListener("pointermove", this.onExpanderMove);
@@ -203,7 +204,7 @@ export class CollectionSchemaView extends CollectionViewBase {
         )
         let previewHandle = !this.props.active() ? (null) : (
             <div className="collectionSchemaView-previewHandle" onPointerDown={this.onExpanderDown} />);
-        let dividerDragger = this._splitPercentage == 100 ? (null) :
+        let dividerDragger = this.splitPercentage == 0 ? (null) :
             <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
@@ -213,7 +214,8 @@ export class CollectionSchemaView extends CollectionViewBase {
                         this._panelHeight = r.entry.height;
                     })}>
                         {({ measureRef }) =>
-                            <div ref={measureRef} className="collectionSchemaView-tableContainer" style={{ width: `${this._splitPercentage}%` }}>
+                            <div ref={measureRef} className="collectionSchemaView-tableContainer"
+                                style={{ width: `calc(100% - ${this.splitPercentage}%)` }}>
                                 <ReactTable
                                     data={children}
                                     pageSize={children.length}
@@ -235,7 +237,7 @@ export class CollectionSchemaView extends CollectionViewBase {
                         }
                     </Measure>
                     {dividerDragger}
-                    <div className="collectionSchemaView-previewRegion" style={{ width: `calc(${100 - this._splitPercentage}% - ${this.DIVIDER_WIDTH}px)` }}>
+                    <div className="collectionSchemaView-previewRegion" style={{ width: `calc(${this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0)}% - ${this.DIVIDER_WIDTH}px)` }}>
                         {content}
                     </div>
                     {previewHandle}
diff --git a/src/client/views/collections/MarqueeView.tsx b/src/client/views/collections/MarqueeView.tsx
index 67716f99a..65aaa837f 100644
--- a/src/client/views/collections/MarqueeView.tsx
+++ b/src/client/views/collections/MarqueeView.tsx
@@ -93,7 +93,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
 
     @action
     marqueeCommand = (e: KeyboardEvent) => {
-        if (e.key == "Backspace") {
+        if (e.key == "Backspace" || e.key == "Delete") {
             this.marqueeSelect().map(d => this.props.removeDocument(d));
             this.props.container.props.Document.SetData(KeyStore.Ink, this.marqueeInkSelect(false), InkField);
             this.cleanupInteractions();
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index fef278cec..8c1ee669f 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -48,16 +48,14 @@ export class VideoBox extends React.Component<FieldViewProps> {
 
         //setTimeout(action(() => this._loaded = true), 500);
         return (
-            <div style={{ width: "100%", height: "100%" }} >
-                <Measure onResize={this.setScaling}>
-                    {({ measureRef }) =>
-                        <video className="videobox-cont" ref={measureRef}>
-                            <source src={path} type="video/mp4" />
-                            Not supported.
+            <Measure onResize={this.setScaling}>
+                {({ measureRef }) =>
+                    <video className="videobox-cont" ref={measureRef}>
+                        <source src={path} type="video/mp4" />
+                        Not supported.
                         </video>
-                    }
-                </Measure>
-            </div>
+                }
+            </Measure>
         )
     }
 }
\ No newline at end of file
diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts
index 0c8b7e260..06cdc8fc8 100644
--- a/src/fields/KeyStore.ts
+++ b/src/fields/KeyStore.ts
@@ -25,6 +25,7 @@ export namespace KeyStore {
     export const LayoutKeys = new Key("LayoutKeys");
     export const LayoutFields = new Key("LayoutFields");
     export const ColumnsKey = new Key("SchemaColumns");
+    export const SchemaSplitPercentage = new Key("SchemaSplitPercentage");
     export const Caption = new Key("Caption");
     export const ActiveFrame = new Key("ActiveFrame");
     export const DocumentText = new Key("DocumentText");
-- 
cgit v1.2.3-70-g09d2


From bf257dfcdb106e73e2e64c384f8f2d3646118376 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 17 Mar 2019 23:49:14 -0400
Subject: fixed context menus on schema views.

---
 src/client/views/collections/CollectionSchemaView.tsx | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 8c1aeef2c..f88a62a0f 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -153,11 +153,11 @@ export class CollectionSchemaView extends CollectionViewBase {
         //     e.preventDefault();
         // } else 
         {
-            if (e.buttons === 1) {
-                if (this.props.isSelected()) {
-                    e.stopPropagation();
-                }
-            }
+            // if (e.buttons === 1) {
+            //     if (this.props.isSelected()) {
+            //         e.stopPropagation();
+            //     }
+            // }
         }
     }
 
-- 
cgit v1.2.3-70-g09d2


From 6cc582d85317c35908d313b4f129617073c5ccac Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Mon, 18 Mar 2019 03:37:22 -0400
Subject: Fixed columns, looks horrible though

---
 .../views/collections/CollectionSchemaView.scss    |  2 +-
 .../views/collections/CollectionSchemaView.tsx     | 90 ++++++++++++++++------
 2 files changed, 68 insertions(+), 24 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 37f4652a9..8d3eba696 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -42,7 +42,7 @@
         height: 100%;
     }
     .ReactTable {
-        position: absolute; // display: inline-block;
+        // position: absolute; // display: inline-block;
         // overflow: auto;
         width: 100%;
         height: 100%;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 16432ebbc..654d13bf1 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -5,7 +5,7 @@ import Measure from "react-measure";
 import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
 import "react-table/react-table.css";
 import { Document } from "../../../fields/Document";
-import { Field } from "../../../fields/Field";
+import { Field, Opt } from "../../../fields/Field";
 import { KeyStore } from "../../../fields/KeyStore";
 import { CompileScript, ToField } from "../../util/Scripting";
 import { Transform } from "../../util/Transform";
@@ -18,11 +18,37 @@ import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
 import { CollectionViewBase } from "./CollectionViewBase";
 import { setupDrag } from "../../util/DragManager";
 import { Key } from "./../../../fields/Key";
+import { Server } from "../../Server";
+import { ListField } from "../../../fields/ListField";
 
 
 // bcz: need to add drag and drop of rows and columns.  This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
 
 
+@observer
+class KeyToggle extends React.Component<{ keyId: string, checked: boolean, toggle: (key: Key) => void }> {
+    @observable
+    key: Key | undefined;
+
+    componentWillReceiveProps() {
+        Server.GetField(this.props.keyId, action((field: Opt<Field>) => {
+            if (field instanceof Key) {
+                this.key = field;
+            }
+        }))
+    }
+
+    render() {
+        if (this.key) {
+            return (<div key={this.key.Id}>
+                <input type="checkbox" checked={this.props.checked} onChange={() => this.key && this.props.toggle(this.key)} />{this.key.Name}
+            </div>)
+        } else {
+            return <div></div>
+        }
+    }
+}
+
 @observer
 export class CollectionSchemaView extends CollectionViewBase {
     private _mainCont = React.createRef<HTMLDivElement>();
@@ -106,26 +132,40 @@ export class CollectionSchemaView extends CollectionViewBase {
         };
     }
 
+    get columns() {
+        return this.props.Document.GetList<Key>(KeyStore.ColumnsKey, []);
+    }
+
     @action
-    addColumn = (k: Key): void => {
-        this._columns.push(k);
-        console.log("adding", this._columns.length);
+    toggleKey = (key: Key) => {
+        this.props.Document.GetOrCreateAsync<ListField<Key>>(KeyStore.ColumnsKey, ListField,
+            (field) => {
+                const index = field.Data.indexOf(key);
+                if (index === -1) {
+                    this.columns.push(key);
+                } else {
+                    this.columns.splice(index, 1);
+                }
+
+            })
     }
 
-    findAllDocumentKeys = (docs: Array<Document>): Set<Key> => {
-        let keys = new Set();
+    @observable keys: Key[] = [];
+
+    findAllDocumentKeys = (): { [id: string]: boolean } => {
+        const docs = this.props.Document.GetList<Document>(this.props.fieldKey, []);
+        let keys: { [id: string]: boolean } = {}
         docs.forEach(doc => {
-            let fields: ObservableMap<string, { key: Key, field: Field }> = doc.Fields;
-            Array.from(fields).map(item => {
-                let v: { key: Key, field: Field } = item[1];
-                let k = v.key;
-                keys.add(k);
-            })
+            let protos = doc.GetAllPrototypes();
+            for (const proto of protos) {
+                proto._proxies.forEach((val: any, key: string) => {
+                    keys[key] = false
+                })
+            }
+        })
+        this.columns.forEach(key => {
+            keys[key.Id] = true;
         })
-        keys.delete(KeyStore.Title);
-        keys.delete(KeyStore.Data);
-        keys.delete(KeyStore.Author);
-        console.log("key set", keys);
         return keys;
     }
 
@@ -206,9 +246,10 @@ export class CollectionSchemaView extends CollectionViewBase {
     focusDocument = (doc: Document) => { }
 
     render() {
-        const columns = this.props.Document.GetList(KeyStore.ColumnsKey, this._columns)
+        const columns = this.columns;
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
         const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined;
+        const allKeys = this.findAllDocumentKeys();
         let content = this._selectedIndex == -1 || !selected ? (null) : (
             <Measure onResize={this.setScaling}>
                 {({ measureRef }) =>
@@ -259,15 +300,18 @@ export class CollectionSchemaView extends CollectionViewBase {
 
                                     }}
                                     getTrProps={this.getTrProps}
+                                    style={{ height: "50%" }}
                                 />
-                                <div className="collectionSchemaView-addColumn" >
-                                    <input type="checkbox" id="addColumn-toggle" />
-                                    <label htmlFor="addColumn-toggle" title="Add Column"><p>+</p></label>
+                                <div className="collectionSchemaView-addColumn" style={{ height: "50%" }} >
+                                    {/* <input type="checkbox" id="addColumn-toggle" />
+                                    <label htmlFor="addColumn-toggle" title="Add Column"><p>+</p></label> */}
 
                                     <div className="addColumn-options">
-                                        <ul>{Array.from(this.findAllDocumentKeys(children)).map(item => {
-                                            return <li onClick={() => this.addColumn(item)}>{item.Name}</li>
-                                        })}</ul>
+                                        <ul>
+                                            {Array.from(Object.keys(allKeys)).map(item => {
+                                                return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
+                                            })}
+                                        </ul>
                                     </div>
                                 </div>
                             </div>
-- 
cgit v1.2.3-70-g09d2


From 8418b842b16da68150243e1750aa8b40eb8a8792 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 18 Mar 2019 11:48:24 -0400
Subject: fixed removing from schemas.  fixed dragging link button to move
 quickly. cleaned up drag/drop code a little

---
 src/client/util/DragManager.ts                     | 12 +++-----
 src/client/views/DocumentDecorations.tsx           | 14 ++++-----
 src/client/views/InkingControl.tsx                 |  3 +-
 .../views/collections/CollectionFreeFormView.tsx   |  4 +--
 src/client/views/collections/CollectionPDFView.tsx |  2 +-
 .../views/collections/CollectionSchemaView.tsx     |  4 +--
 .../views/collections/CollectionVideoView.tsx      |  2 +-
 src/client/views/collections/CollectionView.tsx    |  7 +++--
 .../views/collections/CollectionViewBase.tsx       | 36 ++++++++--------------
 src/client/views/collections/MarqueeView.tsx       | 15 +++++++--
 src/client/views/nodes/DocumentView.tsx            | 16 +++++-----
 11 files changed, 57 insertions(+), 58 deletions(-)

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

diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index c0abec407..54784f2d2 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -2,18 +2,18 @@ import { DocumentDecorations } from "../views/DocumentDecorations";
 import { CollectionDockingView } from "../views/collections/CollectionDockingView";
 import { Document } from "../../fields/Document"
 import { action } from "mobx";
-import { DocumentView } from "../views/nodes/DocumentView";
 import { ImageField } from "../../fields/ImageField";
 import { KeyStore } from "../../fields/KeyStore";
+import { CollectionView } from "../views/collections/CollectionView";
 
-export function setupDrag(_reference: React.RefObject<HTMLDivElement>, docFunc: () => Document) {
+export function setupDrag(_reference: React.RefObject<HTMLDivElement>, docFunc: () => Document, removeFunc: (containingCollection: CollectionView) => void = () => { }) {
     let onRowMove = action((e: PointerEvent): void => {
         e.stopPropagation();
         e.preventDefault();
 
         document.removeEventListener("pointermove", onRowMove);
         document.removeEventListener('pointerup', onRowUp);
-        DragManager.StartDrag(_reference.current!, { document: docFunc() });
+        DragManager.StartDrag(_reference.current!, { draggedDocument: docFunc(), removeDocument: removeFunc });
     });
     let onRowUp = action((e: PointerEvent): void => {
         document.removeEventListener("pointermove", onRowMove);
@@ -122,9 +122,7 @@ export namespace DragManager {
         // bcz: PDFs don't show up if you clone them because they contain a canvas.
         //      however, PDF's have a thumbnail field that contains an image of their canvas.
         //      So we replace the pdf's canvas with the image thumbnail
-        const docView: DocumentView = dragData["documentView"];
-        const doc: Document = dragData["document"];
-
+        const doc: Document = dragData["draggedDocument"];
         if (doc) {
             var pdfBox = dragElement.getElementsByClassName("pdfBox-cont")[0] as HTMLElement;
             let thumbnail = doc.GetT(KeyStore.Thumbnail, ImageField);
@@ -138,7 +136,6 @@ export namespace DragManager {
             }
         }
 
-
         dragDiv.appendChild(dragElement);
 
         let hideSource = false;
@@ -191,6 +188,7 @@ export namespace DragManager {
         if (!target) {
             return;
         }
+        dragData["droppedDocument"] = dragData["aliasOnDrop"] ? (dragData["draggedDocument"] as Document).CreateAlias() : dragData["draggedDocument"];
         target.dispatchEvent(new CustomEvent<DropEvent>("dashOnDrop", {
             bubbles: true,
             detail: {
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 3bdb7d5b3..1145fbe7f 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -77,7 +77,6 @@ export class DocumentDecorations extends React.Component {
     }
 
     onLinkButtonUp = (e: PointerEvent): void => {
-        console.log("up");
         document.removeEventListener("pointermove", this.onLinkButtonMoved)
         document.removeEventListener("pointerup", this.onLinkButtonUp)
         e.stopPropagation();
@@ -85,10 +84,11 @@ export class DocumentDecorations extends React.Component {
 
 
     onLinkButtonMoved = (e: PointerEvent): void => {
-        console.log("moved");
-        let dragData: { [id: string]: any } = {};
-        dragData["linkSourceDoc"] = SelectionManager.SelectedDocuments()[0];
         if (this._linkButton.current != null) {
+            document.removeEventListener("pointermove", this.onLinkButtonMoved)
+            document.removeEventListener("pointerup", this.onLinkButtonUp)
+            let dragData: { [id: string]: any } = {};
+            dragData["linkSourceDoc"] = SelectionManager.SelectedDocuments()[0];
             DragManager.StartDrag(this._linkButton.current, dragData, {
                 handlers: {
                     dragComplete: action(() => { }),
@@ -96,8 +96,6 @@ export class DocumentDecorations extends React.Component {
                 hideSource: false
             })
         }
-        document.removeEventListener("pointermove", this.onLinkButtonMoved)
-        document.removeEventListener("pointerup", this.onLinkButtonUp)
         e.stopPropagation();
     }
 
@@ -217,7 +215,7 @@ export class DocumentDecorations extends React.Component {
                     <LinkMenu docView={selFirst} changeFlyout={this.changeFlyoutContent}>
                     </LinkMenu>
                 }>
-                <div className={"linkButton-" + (selFirst.props.Document.GetData(KeyStore.LinkedToDocs, ListField, []).length ? "nonempty" : "empty")} onPointerDown={this.onLinkButtonDown} ref={this._linkButton}>{linkCount}</div>
+                <div className={"linkButton-" + (selFirst.props.Document.GetData(KeyStore.LinkedToDocs, ListField, []).length ? "nonempty" : "empty")} onPointerDown={this.onLinkButtonDown} >{linkCount}</div>
             </Flyout>);
         }
         return (
@@ -237,7 +235,7 @@ export class DocumentDecorations extends React.Component {
                 <div id="documentDecorations-bottomResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
                 <div id="documentDecorations-bottomRightResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
 
-                <div title="View Links" className="linkFlyout">{linkButton}</div>
+                <div title="View Links" className="linkFlyout" ref={this._linkButton}>{linkButton}</div>
 
             </div >
         )
diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx
index 6616f68d8..ad6bbd476 100644
--- a/src/client/views/InkingControl.tsx
+++ b/src/client/views/InkingControl.tsx
@@ -11,6 +11,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { faPen, faHighlighter, faEraser, faBan } from '@fortawesome/free-solid-svg-icons';
 import { SelectionManager } from "../util/SelectionManager";
 import { KeyStore } from "../../fields/KeyStore";
+import { TextField } from "../../fields/TextField";
 
 library.add(faPen, faHighlighter, faEraser, faBan);
 
@@ -39,7 +40,7 @@ export class InkingControl extends React.Component {
         if (SelectionManager.SelectedDocuments().length == 1) {
             var sdoc = SelectionManager.SelectedDocuments()[0];
             if (sdoc.props.ContainingCollectionView && sdoc.props.ContainingCollectionView) {
-                sdoc.props.Document.SetText(KeyStore.BackgroundColor, color.hex);
+                sdoc.props.Document.SetOnPrototype(KeyStore.BackgroundColor, new TextField(color.hex));
             }
         }
     }
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 728076ef8..85ea2d121 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -28,7 +28,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
         // mark this collection so that when the text box is created we can send it the SelectOnLoad prop to focus itself
         this._selectOnLoaded = newBox.Id;
         //set text to be the typed key and get focus on text box
-        this.props.addDocument(newBox);
+        this.props.addDocument(newBox, false);
         //remove cursor from screen
         this.PreviewCursorVisible = false;
     }
@@ -79,7 +79,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
         let screenX = de.x - (de.data["xOffset"] as number || 0);
         let screenY = de.y - (de.data["yOffset"] as number || 0);
         const [x, y] = this.getTransform().transformPoint(screenX, screenY);
-        let doc: Document = de.data["document"];
+        let doc: Document = de.data["droppedDocument"];
         if (doc) {
             doc.SetNumber(KeyStore.X, x);
             doc.SetNumber(KeyStore.Y, y);
diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx
index 124d82c8b..e64b4c945 100644
--- a/src/client/views/collections/CollectionPDFView.tsx
+++ b/src/client/views/collections/CollectionPDFView.tsx
@@ -38,7 +38,7 @@ export class CollectionPDFView extends React.Component<CollectionViewProps> {
     public SelectedDocs: FieldId[] = []
     public active: () => boolean = () => CollectionView.Active(this);
 
-    addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); }
+    addDocument = (doc: Document, allowDuplicates: boolean): void => { CollectionView.AddDocument(this.props, doc, allowDuplicates); }
     removeDocument = (doc: Document): boolean => { return CollectionView.RemoveDocument(this.props, doc); }
 
     specificContextMenu = (e: React.MouseEvent): void => {
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index f88a62a0f..ced08a14e 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -14,7 +14,7 @@ import { EditableView } from "../EditableView";
 import { DocumentView } from "../nodes/DocumentView";
 import { FieldView, FieldViewProps } from "../nodes/FieldView";
 import "./CollectionSchemaView.scss";
-import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
+import { COLLECTION_BORDER_WIDTH, CollectionView } from "./CollectionView";
 import { CollectionViewBase } from "./CollectionViewBase";
 import { setupDrag } from "../../util/DragManager";
 
@@ -47,7 +47,7 @@ export class CollectionSchemaView extends CollectionViewBase {
             <FieldView {...props} />
         )
         let reference = React.createRef<HTMLDivElement>();
-        let onItemDown = setupDrag(reference, () => props.doc);
+        let onItemDown = setupDrag(reference, () => props.doc, (containingCollection: CollectionView) => this.props.removeDocument(props.doc));
         return (
             <div className="collectionSchemaView-cellContents" onPointerDown={onItemDown} style={{ height: "36px" }} key={props.doc.Id} ref={reference}>
                 <EditableView contents={contents}
diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx
index 8fc1a1b4d..05f759967 100644
--- a/src/client/views/collections/CollectionVideoView.tsx
+++ b/src/client/views/collections/CollectionVideoView.tsx
@@ -44,7 +44,7 @@ export class CollectionVideoView extends React.Component<CollectionViewProps> {
     public SelectedDocs: FieldId[] = []
     public active: () => boolean = () => CollectionView.Active(this);
 
-    addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); }
+    addDocument = (doc: Document, allowDuplicates: boolean): void => { CollectionView.AddDocument(this.props, doc, allowDuplicates); }
     removeDocument = (doc: Document): boolean => { return CollectionView.RemoveDocument(this.props, doc); }
 
     specificContextMenu = (e: React.MouseEvent): void => {
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 40acf466e..303099c16 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -36,7 +36,7 @@ export class CollectionView extends React.Component<CollectionViewProps> {
     @observable
     public SelectedDocs: FieldId[] = [];
     public active: () => boolean = () => CollectionView.Active(this);
-    addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); }
+    addDocument = (doc: Document, allowDuplicates: boolean): void => { CollectionView.AddDocument(this.props, doc, allowDuplicates); }
     removeDocument = (doc: Document): boolean => { return CollectionView.RemoveDocument(this.props, doc); }
     get subView() { return CollectionView.SubView(this); }
 
@@ -48,12 +48,13 @@ export class CollectionView extends React.Component<CollectionViewProps> {
     }
 
     @action
-    public static AddDocument(props: CollectionViewProps, doc: Document) {
+    public static AddDocument(props: CollectionViewProps, doc: Document, allowDuplicates: boolean) {
         doc.SetNumber(KeyStore.Page, props.Document.GetNumber(KeyStore.CurPage, -1));
         if (props.Document.Get(props.fieldKey) instanceof Field) {
             //TODO This won't create the field if it doesn't already exist
             const value = props.Document.GetData(props.fieldKey, ListField, new Array<Document>())
-            value.push(doc);
+            if (!value.some(v => v.Id == doc.Id) || allowDuplicates)
+                value.push(doc);
         } else {
             props.Document.SetOnPrototype(props.fieldKey, new ListField([doc]));
         }
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index 3d1a76a07..0358b5907 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -27,7 +27,7 @@ export interface CollectionViewProps {
 }
 export interface SubCollectionViewProps extends CollectionViewProps {
     active: () => boolean;
-    addDocument: (doc: Document) => void;
+    addDocument: (doc: Document, allowDuplicates: boolean) => void;
     removeDocument: (doc: Document) => boolean;
     CollectionView: CollectionView;
 }
@@ -46,28 +46,16 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
     @undoBatch
     @action
     protected drop(e: Event, de: DragManager.DropEvent) {
-        let docToAlias = de.data["documentToAlias"];
-        let docView = de.data["documentView"];
-        let doc = docToAlias ? docToAlias.CreateAlias() : de.data["document"];
-        if (docToAlias) {
-            [KeyStore.Width, KeyStore.Height].map(key =>
-                docToAlias.GetTAsync(key, NumberField, (f: Opt<NumberField>) => {
-                    if (f) {
-                        doc.SetNumber(key, f.Data)
-                    }
-                })
-            );
-            de.data["document"] = doc;
-            this.props.addDocument(doc);
-        } else if (docView) {
-            if (doc && docView.props.RemoveDocument && docView.props.ContainingCollectionView !== this.props.CollectionView) {
-                docView.props.RemoveDocument(doc);
-                this.props.removeDocument(doc); // bcz: not good -- want to check if it's there and then add if it isn't
-                this.props.addDocument(doc);
+        let dropped = de.data["droppedDocument"];
+        if (dropped) {
+            if (de.data["aliasOnDrop"]) {
+                let dragged = de.data["draggedDocument"];
+                [KeyStore.Width, KeyStore.Height, KeyStore.CurPage].map(key =>
+                    dragged.GetTAsync(key, NumberField, (f: Opt<NumberField>) => f ? dropped.SetNumber(key, f.Data) : null));
+            } else if (de.data["removeDocument"]) {
+                de.data["removeDocument"](this.props.CollectionView);
             }
-        } else if (doc) {
-            this.props.removeDocument(doc); // bcz: not good -- want to check if it's there and then add if it isn't
-            this.props.addDocument(doc);
+            this.props.addDocument(dropped, false);
         }
         e.stopPropagation();
     }
@@ -89,7 +77,7 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
             console.log("not good");
             let htmlDoc = Documents.HtmlDocument(html, { ...options, width: 300, height: 300 });
             htmlDoc.SetText(KeyStore.DocumentText, text);
-            this.props.addDocument(htmlDoc);
+            this.props.addDocument(htmlDoc, false);
             return;
         }
 
@@ -99,7 +87,7 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
             const upload = window.location.origin + "/upload";
             let item = e.dataTransfer.items[i];
             if (item.kind === "string" && item.type.indexOf("uri") != -1) {
-                e.dataTransfer.items[i].getAsString(action((s: string) => this.props.addDocument(Documents.WebDocument(s, options))))
+                e.dataTransfer.items[i].getAsString(action((s: string) => this.props.addDocument(Documents.WebDocument(s, options), false)))
             }
             let type = item.type
             console.log(type)
diff --git a/src/client/views/collections/MarqueeView.tsx b/src/client/views/collections/MarqueeView.tsx
index f5c83a934..8c2f3443c 100644
--- a/src/client/views/collections/MarqueeView.tsx
+++ b/src/client/views/collections/MarqueeView.tsx
@@ -17,7 +17,7 @@ interface MarqueeViewProps {
     getMarqueeTransform: () => Transform;
     getTransform: () => Transform;
     container: CollectionFreeFormView;
-    addDocument: (doc: Document) => void;
+    addDocument: (doc: Document, allowDuplicates: false) => void;
     activeDocuments: () => Document[];
     selectDocuments: (docs: Document[]) => void;
     removeDocument: (doc: Document) => boolean;
@@ -111,7 +111,18 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
             let liftedInk = this.marqueeInkSelect(true);
             this.props.container.props.Document.SetData(KeyStore.Ink, this.marqueeInkSelect(false), InkField);
             //setTimeout(() => {
-            this.props.addDocument(Documents.FreeformDocument(selected, { x: bounds.left, y: bounds.top, panx: 0, pany: 0, width: bounds.width, backgroundColor: "Transparent", height: bounds.height, ink: liftedInk, title: "a nested collection" }));
+            let newCollection = Documents.FreeformDocument(selected, {
+                x: bounds.left,
+                y: bounds.top,
+                panx: 0,
+                pany: 0,
+                width: bounds.width,
+                height: bounds.height,
+                backgroundColor: "Transparent",
+                ink: liftedInk,
+                title: "a nested collection"
+            });
+            this.props.addDocument(newCollection, false);
             // }, 100);
             this.cleanupInteractions();
         }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index fbd58ef7e..e98815fa6 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -23,7 +23,7 @@ import React = require("react");
 export interface DocumentViewProps {
     ContainingCollectionView: Opt<CollectionView>;
     Document: Document;
-    AddDocument?: (doc: Document) => void;
+    AddDocument?: (doc: Document, allowDuplicates: boolean) => void;
     RemoveDocument?: (doc: Document) => boolean;
     ScreenToLocalTransform: () => Transform;
     isTopMost: boolean;
@@ -164,12 +164,15 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         if (this._mainCont.current) {
             const [left, top] = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
             let dragData: { [id: string]: any } = {};
-            dragData["documentView"] = this;
-            if (dropAliasOfDraggedDoc)
-                dragData["documentToAlias"] = this.props.Document;
-            dragData["document"] = this.props.Document;
+            dragData["aliasOnDrop"] = dropAliasOfDraggedDoc;
+            dragData["draggedDocument"] = this.props.Document;
             dragData["xOffset"] = x - left;
             dragData["yOffset"] = y - top;
+            dragData["removeDocument"] = (dropCollectionView: CollectionView) => {
+                if (this.props.RemoveDocument && this.props.ContainingCollectionView !== dropCollectionView) {
+                    this.props.RemoveDocument(this.props.Document);
+                }
+            }
             DragManager.StartDrag(this._mainCont.current, dragData, {
                 handlers: {
                     dragComplete: action(() => { }),
@@ -213,7 +216,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
 
     fieldsClicked = (e: React.MouseEvent): void => {
         if (this.props.AddDocument) {
-            this.props.AddDocument(Documents.KVPDocument(this.props.Document, { width: 300, height: 300 }));
+            this.props.AddDocument(Documents.KVPDocument(this.props.Document, { width: 300, height: 300 }), false);
         }
     }
     fullScreenClicked = (e: React.MouseEvent): void => {
@@ -232,7 +235,6 @@ export class DocumentView extends React.Component<DocumentViewProps> {
 
     @action
     drop = (e: Event, de: DragManager.DropEvent) => {
-        console.log("drop");
         const sourceDocView: DocumentView = de.data["linkSourceDoc"];
         if (!sourceDocView) {
             return;
-- 
cgit v1.2.3-70-g09d2


From da576c10538c025f247a50ed8561b112f78f828e Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 18 Mar 2019 14:02:21 -0400
Subject: added column dividers

---
 .../views/collections/CollectionSchemaView.scss    | 17 ++++
 .../views/collections/CollectionSchemaView.tsx     | 90 ++++++++++++++++------
 2 files changed, 84 insertions(+), 23 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 8d3eba696..863bb256a 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -28,6 +28,23 @@
         top: 0;
         background: $main-accent;
     }
+    .collectionSchemaView-columnsHandle {
+        position: absolute;
+        height: 37px;
+        width: 20px;
+        z-index: 20;
+        left: 0;
+        bottom: 0;
+        background: $main-accent;
+    }
+    .collectionSchemaView-colDividerDragger {
+        position: relative;
+        box-sizing: border-box;
+        border-top: 1px solid $intermediate-color;
+        border-bottom: 1px solid $intermediate-color;
+        float: top;
+        width: 100%;
+    }
     .collectionSchemaView-dividerDragger {
         position: relative;
         box-sizing: border-box;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 654d13bf1..76ee421d6 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -60,6 +60,7 @@ export class CollectionSchemaView extends CollectionViewBase {
     @observable _panelWidth = 0;
     @observable _panelHeight = 0;
     @observable _selectedIndex = 0;
+    @observable _columnsPercentage = 0;
     @computed get splitPercentage() { return this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0); }
 
     renderCell = (rowProps: CellInfo) => {
@@ -190,6 +191,25 @@ export class CollectionSchemaView extends CollectionViewBase {
         document.addEventListener("pointermove", this.onDividerMove);
         document.addEventListener('pointerup', this.onDividerUp);
     }
+
+
+    @action
+    onColDividerMove = (e: PointerEvent): void => {
+        let nativeWidth = this._mainCont.current!.getBoundingClientRect();
+        this._columnsPercentage = 100 - (e.clientY - nativeWidth.top) / nativeWidth.height * 100;
+    }
+    @action
+    onColDividerUp = (e: PointerEvent): void => {
+        document.removeEventListener("pointermove", this.onColDividerMove);
+        document.removeEventListener('pointerup', this.onColDividerUp);
+    }
+    onColDividerDown = (e: React.PointerEvent) => {
+        e.stopPropagation();
+        e.preventDefault();
+        document.addEventListener("pointermove", this.onColDividerMove);
+        document.addEventListener('pointerup', this.onColDividerUp);
+    }
+
     @action
     onExpanderMove = (e: PointerEvent): void => {
         e.stopPropagation();
@@ -201,12 +221,8 @@ export class CollectionSchemaView extends CollectionViewBase {
         e.preventDefault();
         document.removeEventListener("pointermove", this.onExpanderMove);
         document.removeEventListener('pointerup', this.onExpanderUp);
-        if (this._startSplitPercent == this.splitPercentage) {
-            this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0);
-        }
     }
     onExpanderDown = (e: React.PointerEvent) => {
-        this._startSplitPercent = this.splitPercentage;
         e.stopPropagation();
         e.preventDefault();
         document.addEventListener("pointermove", this.onExpanderMove);
@@ -227,6 +243,27 @@ export class CollectionSchemaView extends CollectionViewBase {
         }
     }
 
+    @action
+    onColumnsMove = (e: PointerEvent): void => {
+        e.stopPropagation();
+        e.preventDefault();
+    }
+    @action
+    onColumnsUp = (e: PointerEvent): void => {
+        e.stopPropagation();
+        e.preventDefault();
+        document.removeEventListener("pointermove", this.onColumnsMove);
+        document.removeEventListener('pointerup', this.onColumnsUp);
+        this._columnsPercentage = this._columnsPercentage ? 0 : 50;
+    }
+    onColumnsDown = (e: React.PointerEvent) => {
+        this._startSplitPercent = this.splitPercentage;
+        e.stopPropagation();
+        e.preventDefault();
+        document.addEventListener("pointermove", this.onColumnsMove);
+        document.addEventListener('pointerup', this.onColumnsUp);
+    }
+
     @action
     setScaling = (r: any) => {
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
@@ -271,8 +308,12 @@ export class CollectionSchemaView extends CollectionViewBase {
         )
         let previewHandle = !this.props.active() ? (null) : (
             <div className="collectionSchemaView-previewHandle" onPointerDown={this.onExpanderDown} />);
+        let columnsHandle = !this.props.active() ? (null) : (
+            <div className="collectionSchemaView-columnsHandle" onPointerDown={this.onColumnsDown} />);
         let dividerDragger = this.splitPercentage == 0 ? (null) :
             <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />
+        let colDividerDragger = this._columnsPercentage == 0 ? (null) :
+            <div className="collectionSchemaView-colDividerDragger" onPointerDown={this.onColDividerDown} style={{ height: `${this.DIVIDER_WIDTH}px` }} />
 
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
@@ -284,30 +325,32 @@ export class CollectionSchemaView extends CollectionViewBase {
                         {({ measureRef }) =>
                             <div ref={measureRef} className="collectionSchemaView-tableContainer"
                                 style={{ width: `calc(100% - ${this.splitPercentage}%)` }}>
-                                <ReactTable
-                                    data={children}
-                                    pageSize={children.length}
-                                    page={0}
-                                    showPagination={false}
-                                    columns={columns.map(col => ({
-                                        Header: col.Name,
-                                        accessor: (doc: Document) => [doc, col],
-                                        id: col.Id
-                                    }))}
-                                    column={{
-                                        ...ReactTableDefaults.column,
-                                        Cell: this.renderCell,
+                                <div className="collectionSchemaView-reactContainer" style={{ height: `calc(100% - ${this._columnsPercentage}%)` }}>
+                                    <ReactTable
+                                        data={children}
+                                        pageSize={children.length}
+                                        page={0}
+                                        showPagination={false}
+                                        columns={columns.map(col => ({
+                                            Header: col.Name,
+                                            accessor: (doc: Document) => [doc, col],
+                                            id: col.Id
+                                        }))}
+                                        column={{
+                                            ...ReactTableDefaults.column,
+                                            Cell: this.renderCell,
 
-                                    }}
-                                    getTrProps={this.getTrProps}
-                                    style={{ height: "50%" }}
-                                />
-                                <div className="collectionSchemaView-addColumn" style={{ height: "50%" }} >
+                                        }}
+                                        getTrProps={this.getTrProps}
+                                    />
+                                </div>
+                                {colDividerDragger}
+                                <div className="collectionSchemaView-addColumn" style={{ height: `${this._columnsPercentage}%` }} >
                                     {/* <input type="checkbox" id="addColumn-toggle" />
                                     <label htmlFor="addColumn-toggle" title="Add Column"><p>+</p></label> */}
 
                                     <div className="addColumn-options">
-                                        <ul>
+                                        <ul style={{ overflow: "scroll" }}>
                                             {Array.from(Object.keys(allKeys)).map(item => {
                                                 return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
                                             })}
@@ -322,6 +365,7 @@ export class CollectionSchemaView extends CollectionViewBase {
                         {content}
                     </div>
                     {previewHandle}
+                    {columnsHandle}
 
                 </div>
             </div >
-- 
cgit v1.2.3-70-g09d2


From f70ad315167b714f11f7d68f35a46abe9e525a4d Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Mon, 18 Mar 2019 14:51:06 -0400
Subject: Fixed schema stuff

---
 src/client/views/collections/CollectionSchemaView.tsx | 4 ++++
 1 file changed, 4 insertions(+)

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

diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 1c5ff1b12..50f5e9618 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -223,8 +223,12 @@ export class CollectionSchemaView extends CollectionViewBase {
         e.preventDefault();
         document.removeEventListener("pointermove", this.onExpanderMove);
         document.removeEventListener('pointerup', this.onExpanderUp);
+        if (this._startSplitPercent == this.splitPercentage) {
+            this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0);
+        }
     }
     onExpanderDown = (e: React.PointerEvent) => {
+        this._startSplitPercent = this.splitPercentage;
         e.stopPropagation();
         e.preventDefault();
         document.addEventListener("pointermove", this.onExpanderMove);
-- 
cgit v1.2.3-70-g09d2


From 67170e521366f8178645cc85aaf377e53b1a6f21 Mon Sep 17 00:00:00 2001
From: laurawilsonri <laura_wilson@brown.edu>
Date: Mon, 18 Mar 2019 18:07:46 -0400
Subject: ui in place, needs refinement and more backend

---
 deploy/index.html                                  |   2 +
 package-lock.json                                  | 239 ++++++++++++++++++++-
 package.json                                       |   7 +-
 src/client/views/DocumentDecorations.tsx           |   4 +-
 .../views/collections/CollectionSchemaView.scss    |  66 +++++-
 .../views/collections/CollectionSchemaView.tsx     |  68 +++++-
 6 files changed, 373 insertions(+), 13 deletions(-)

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

diff --git a/deploy/index.html b/deploy/index.html
index e0892662a..94699126c 100644
--- a/deploy/index.html
+++ b/deploy/index.html
@@ -3,6 +3,8 @@
 <head>
   <title>Dash Web</title>
   <link href="https://fonts.googleapis.com/css?family=Fjalla+One|Hind+Siliguri:300" rel="stylesheet">
+  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
+    integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
   <script src="https://cdnjs.cloudflare.com/ajax/libs/typescript/3.3.1/typescript.min.js"></script>
 </head>
 
diff --git a/package-lock.json b/package-lock.json
index 5b9cb598d..3d66773f2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -174,6 +174,52 @@
       "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz",
       "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw=="
     },
+    "@react-bootstrap/react-popper": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@react-bootstrap/react-popper/-/react-popper-1.2.1.tgz",
+      "integrity": "sha512-4l3q7LcZEhrSkI4d3Ie3g4CdrXqqTexXX4PFT45CB0z5z2JUbaxgRwKNq7r5j2bLdVpZm+uvUGqxJw8d9vgbJQ==",
+      "requires": {
+        "babel-runtime": "6.x.x",
+        "create-react-context": "^0.2.1",
+        "popper.js": "^1.14.4",
+        "prop-types": "^15.6.1",
+        "typed-styles": "^0.0.5",
+        "warning": "^3.0.0"
+      }
+    },
+    "@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.3.0",
+      "resolved": "https://registry.npmjs.org/@trendmicro/react-dropdown/-/react-dropdown-1.3.0.tgz",
+      "integrity": "sha512-KwL0ksEZPay7qNsiGcPQ3aGmyfJCcUuIjiD9HZs6L66ScwSRoFkDlAjMTlRVLFcYVNhpuyUH4pPiFlKQQzDHGQ==",
+      "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": "^5.0.0",
+        "warning": "^3.0.0"
+      },
+      "dependencies": {
+        "uncontrollable": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-5.1.0.tgz",
+          "integrity": "sha512-5FXYaFANKaafg4IVZXUNtGyzsnYEvqlr9wQ3WpZxFpEUxl29A3H6Q4G1Dnnorvq9TGOGATBApWR4YpLAh+F5hw==",
+          "requires": {
+            "invariant": "^2.2.4"
+          }
+        }
+      }
+    },
     "@types/anymatch": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
@@ -1531,6 +1577,11 @@
         }
       }
     },
+    "bootstrap": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz",
+      "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
+    },
     "boxen": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
@@ -1899,6 +1950,11 @@
         "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="
+    },
     "character-parser": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
@@ -3461,6 +3517,20 @@
         "websocket-driver": ">=0.5.1"
       }
     },
+    "fbjs": {
+      "version": "0.8.17",
+      "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
+      "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
+      "requires": {
+        "core-js": "^1.0.0",
+        "isomorphic-fetch": "^2.1.1",
+        "loose-envify": "^1.0.0",
+        "object-assign": "^4.1.0",
+        "promise": "^7.1.1",
+        "setimmediate": "^1.0.5",
+        "ua-parser-js": "^0.7.18"
+      }
+    },
     "figgy-pudding": {
       "version": "3.5.1",
       "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz",
@@ -3735,14 +3805,12 @@
         "balanced-match": {
           "version": "1.0.0",
           "resolved": false,
-          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-          "optional": true
+          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
         },
         "brace-expansion": {
           "version": "1.1.11",
           "resolved": false,
           "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -3762,8 +3830,7 @@
         "concat-map": {
           "version": "0.0.1",
           "resolved": false,
-          "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-          "optional": true
+          "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
         },
         "console-control-strings": {
           "version": "1.1.0",
@@ -3911,7 +3978,6 @@
           "version": "3.0.4",
           "resolved": false,
           "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
@@ -4927,6 +4993,14 @@
       "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==",
       "dev": true
     },
+    "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",
@@ -5440,6 +5514,11 @@
       "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.0.tgz",
       "integrity": "sha512-6hHxsp9e6zQU8nXsP+02HGWXwTkOEw6IROhF2ZA28cYbUk4eJ6QbtZvdqZOdD9YPKghG3apk5eOCvs+tLl3lRg=="
     },
+    "keycode": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz",
+      "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ="
+    },
     "killable": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@@ -9983,6 +10062,11 @@
         }
       }
     },
+    "popper.js": {
+      "version": "1.14.7",
+      "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.7.tgz",
+      "integrity": "sha512-4q1hNvoUre/8srWsH7hnoSJ5xVmIL4qgz+s4qf2TnJIMyZFUFMGH+9vE7mXynAlHSZ/NdTmmow86muD0myUkVQ=="
+    },
     "portfinder": {
       "version": "1.0.20",
       "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz",
@@ -10168,6 +10252,15 @@
         "react-is": "^16.8.1"
       }
     },
+    "prop-types-extra": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.0.tgz",
+      "integrity": "sha512-QFyuDxvMipmIVKD2TwxLVPzMnO4e5oOf1vr3tJIomL8E7d0lr6phTHd5nkPhFIzTD1idBLLEPeylL9g+rrTzRg==",
+      "requires": {
+        "react-is": "^16.3.2",
+        "warning": "^3.0.0"
+      }
+    },
     "prosemirror-commands": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.0.7.tgz",
@@ -10605,6 +10698,43 @@
         "scheduler": "^0.13.4"
       }
     },
+    "react-bootstrap": {
+      "version": "1.0.0-beta.5",
+      "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.0.0-beta.5.tgz",
+      "integrity": "sha512-Osm0OtTbYwfsT1rpu88ESWuAHZxfaHFNKFiW8w3w+6YY9/bLEPHbGRZA6W21fg5yvcuKN9hJKT857TTHgY7SoQ==",
+      "requires": {
+        "@babel/runtime": "^7.2.0",
+        "@react-bootstrap/react-popper": "1.2.1",
+        "classnames": "^2.2.6",
+        "dom-helpers": "^3.4.0",
+        "invariant": "^2.2.3",
+        "keycode": "^2.1.2",
+        "popper.js": "^1.14.6",
+        "prop-types": "^15.6.2",
+        "prop-types-extra": "^1.1.0",
+        "react-context-toolbox": "^2.0.2",
+        "react-overlays": "^1.0.0",
+        "react-prop-types": "^0.4.0",
+        "react-transition-group": "^2.5.1",
+        "uncontrollable": "^6.0.0",
+        "warning": "^4.0.1"
+      },
+      "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-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.17.0",
       "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.17.0.tgz",
@@ -10618,6 +10748,11 @@
         "tinycolor2": "^1.4.1"
       }
     },
+    "react-context-toolbox": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/react-context-toolbox/-/react-context-toolbox-2.0.2.tgz",
+      "integrity": "sha512-tY4j0imkYC3n5ZlYSgFkaw7fmlCp3IoQQ6DxpqeNHzcD0hf+6V+/HeJxviLUZ1Rv1Yn3N3xyO2EhkkZwHn0m1A=="
+    },
     "react-dimensions": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/react-dimensions/-/react-dimensions-1.3.1.tgz",
@@ -10714,6 +10849,31 @@
         "threads": "^0.8.0"
       }
     },
+    "react-overlays": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-1.2.0.tgz",
+      "integrity": "sha512-i/FCV8wR6aRaI+Kz/dpJhOdyx+ah2tN1RhT9InPrexyC4uzf3N4bNayFTGtUeQVacj57j1Mqh1CwV60/5153Iw==",
+      "requires": {
+        "classnames": "^2.2.6",
+        "dom-helpers": "^3.4.0",
+        "prop-types": "^15.6.2",
+        "prop-types-extra": "^1.1.0",
+        "react-context-toolbox": "^2.0.2",
+        "react-popper": "^1.3.2",
+        "uncontrollable": "^6.0.0",
+        "warning": "^4.0.2"
+      },
+      "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-pdf": {
       "version": "4.0.5",
       "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-4.0.5.tgz",
@@ -10791,6 +10951,51 @@
       "resolved": "https://registry.npmjs.org/react-pointable/-/react-pointable-1.1.3.tgz",
       "integrity": "sha512-7skalWy38NLyKk1HcITmuloqCe2INPh69cFHbN7NcCn+Wfb0Ha4XGwGN0iVa4ZzqIHSqFRYOmV0loYNHrZ5/Sg=="
     },
+    "react-popper": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.3.tgz",
+      "integrity": "sha512-ynMZBPkXONPc5K4P5yFWgZx5JGAUIP3pGGLNs58cfAPgK67olx7fmLp+AdpZ0+GoQ+ieFDa/z4cdV6u7sioH6w==",
+      "requires": {
+        "@babel/runtime": "^7.1.2",
+        "create-react-context": "<=0.2.2",
+        "popper.js": "^1.14.4",
+        "prop-types": "^15.6.1",
+        "typed-styles": "^0.0.7",
+        "warning": "^4.0.2"
+      },
+      "dependencies": {
+        "create-react-context": {
+          "version": "0.2.2",
+          "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.2.tgz",
+          "integrity": "sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A==",
+          "requires": {
+            "fbjs": "^0.8.0",
+            "gud": "^1.0.0"
+          }
+        },
+        "typed-styles": {
+          "version": "0.0.7",
+          "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz",
+          "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q=="
+        },
+        "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-prop-types": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/react-prop-types/-/react-prop-types-0.4.0.tgz",
+      "integrity": "sha1-+ZsL+0AGkpya8gUefBQUpcdbk9A=",
+      "requires": {
+        "warning": "^3.0.0"
+      }
+    },
     "react-rnd": {
       "version": "7.4.3",
       "resolved": "https://registry.npmjs.org/react-rnd/-/react-rnd-7.4.3.tgz",
@@ -10800,6 +11005,15 @@
         "react-draggable": "^3.0.5"
       }
     },
+    "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.85",
       "resolved": "https://registry.npmjs.org/react-split-pane/-/react-split-pane-0.1.85.tgz",
@@ -12453,6 +12667,11 @@
         "mime-types": "~2.1.18"
       }
     },
+    "typed-styles": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.5.tgz",
+      "integrity": "sha512-ht+rEe5UsdEBAa3gr64+QjUOqjOLJfWLvl5HZR5Ev9uo/OnD3p43wPeFSB1hNFc13GXQF/JU1Bn0YHLUqBRIlw=="
+    },
     "typedarray": {
       "version": "0.0.6",
       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
@@ -12526,6 +12745,14 @@
         "random-bytes": "~1.0.0"
       }
     },
+    "uncontrollable": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-6.1.0.tgz",
+      "integrity": "sha512-2TzEm0pLKauMBZfAZXsgQvLpZHEp95891frCZdGDrSG7dWYaIQhedwLAzi0X8pR8KHNqlmuYEb2cEgbQzr050A==",
+      "requires": {
+        "invariant": "^2.2.4"
+      }
+    },
     "undefsafe": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz",
diff --git a/package.json b/package.json
index 3bbaf72ad..3a1928632 100644
--- a/package.json
+++ b/package.json
@@ -35,9 +35,10 @@
   "dependencies": {
     "@fortawesome/fontawesome-free-solid": "^5.0.13",
     "@fortawesome/fontawesome-svg-core": "^1.2.15",
-    "@hig/flyout": "^1.0.3",
     "@fortawesome/free-solid-svg-icons": "^5.7.2",
     "@fortawesome/react-fontawesome": "^0.1.4",
+    "@hig/flyout": "^1.0.3",
+    "@trendmicro/react-dropdown": "^1.3.0",
     "@types/bcrypt-nodejs": "0.0.30",
     "@types/bluebird": "^3.5.25",
     "@types/body-parser": "^1.17.0",
@@ -78,6 +79,7 @@
     "bcrypt-nodejs": "0.0.3",
     "bluebird": "^3.5.3",
     "body-parser": "^1.18.3",
+    "bootstrap": "^4.3.1",
     "connect-mongo": "^2.0.3",
     "express": "^4.16.4",
     "express-flash": "0.0.2",
@@ -116,6 +118,8 @@
     "pug": "^2.0.3",
     "raw-loader": "^1.0.0",
     "react": "^16.8.4",
+    "react-bootstrap": "^1.0.0-beta.5",
+    "react-bootstrap-dropdown-menu": "^1.1.15",
     "react-color": "^2.17.0",
     "react-dimensions": "^1.3.1",
     "react-dom": "^16.8.4",
@@ -127,6 +131,7 @@
     "react-pdf": "^4.0.2",
     "react-pdf-highlighter": "^2.1.2",
     "react-pdf-js": "^4.0.2",
+    "react-simple-dropdown": "^3.2.3",
     "react-split-pane": "^0.1.85",
     "react-table": "^6.9.2",
     "request": "^2.88.0",
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index dc62f97cf..1aa6d1936 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -10,8 +10,8 @@ import { DragManager } from "../util/DragManager";
 import { LinkMenu } from "./nodes/LinkMenu";
 import { ListField } from "../../fields/ListField";
 const higflyout = require("@hig/flyout");
-const { anchorPoints } = higflyout;
-const Flyout = higflyout.default;
+export const { anchorPoints } = higflyout;
+export const Flyout = higflyout.default;
 
 @observer
 export class DocumentDecorations extends React.Component {
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index d40e6d314..ab906cf4b 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -1,5 +1,65 @@
+//options menu styling
+#schemaOptionsMenuBtn {
+    position: absolute;
+    height: 15px;
+    width: 15px;
+    border-radius: 50%;
+    z-index: 21; 
+    right: 3px;
+    top: 3px; 
+    pointer-events: auto;
+    background-color:red;
+}
+
+.dd-item-containter:hover {
+  background-color: rgb(204, 204, 204);
+}
+
+.dd-item {
+    color: black;
+    padding-left: 6px;
+    padding-bottom: 0px;
+    padding-top: 4px;
+    font-size: 12px;
+    margin: 0px;
+    display: block;
+    width: 100%;
+    height: 25px;
+    z-index: 100;
+}
+.dd-item:hover {
+    color: black;
+    font-weight: 500;
+}
+
+.dropdown-menu {
+    height: 100px;
+    overflow-y: scroll;
+  }
 
+#dropdown-basic-button {
+    background-color: #fff;
+    border: .75px solid #bbbbbb;
+    border-radius: 0;
+    -webkit-box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
+    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+    margin:10px;
+    margin-top: 8px;
+    color: black;
+    display: inline-block;
+    width: 160px;
+    height: 25px;
+    font-size: 15px;
+    padding: 0px;
+    border-radius: 3px;
+    font-size: 12px;
+  }
 
+  #options-flyout-div {
+    text-align: center;
+    padding:0px;
+  }
+  
 .collectionSchemaView-container {
     border-style: solid;
     box-sizing: border-box;
@@ -14,11 +74,11 @@
     }
     .collectionSchemaView-previewHandle {
         position: absolute;
-        height: 37px;
-        width: 20px; 
+        height: 15px;
+        width: 15px; 
         z-index: 20; 
         right: 0; 
-        top: 0; 
+        top: 20px; 
         background: Black ;
     }
     .collectionSchemaView-dividerDragger{
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 04f017378..7c87ef744 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,4 +1,4 @@
-import React = require("react")
+import React = require("react");
 import { action, observable } from "mobx";
 import { observer } from "mobx-react";
 import Measure from "react-measure";
@@ -17,6 +17,16 @@ import "./CollectionSchemaView.scss";
 import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
 import { CollectionViewBase } from "./CollectionViewBase";
 import { setupDrag } from "../../util/DragManager";
+import '../DocumentDecorations.scss';
+import { Flyout, anchorPoints } from "../DocumentDecorations";
+import { DropdownButton, Dropdown } from 'react-bootstrap';
+import { ListField } from "../../../fields/ListField";
+import { Key } from "../../../fields/Key";
+//import { Server } from "http";
+//import { Server } from "http";
+import { Server } from "../../Server";
+
+//import { MenuItem } from 'react-bootstrap';
 
 // bcz: need to add drag and drop of rows and columns.  This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
 
@@ -178,6 +188,19 @@ export class CollectionSchemaView extends CollectionViewBase {
 
     focusDocument = (doc: Document) => { }
 
+    keyDropDownOnSelect = (keyId: string) => {
+        const columns = this.props.Document.GetList(KeyStore.ColumnsKey, [KeyStore.Title, KeyStore.Data, KeyStore.Author]);
+        const listOfFields = this.props.Document.GetList<Document>(this.props.fieldKey, [])[1].fields;
+        if (listOfFields.has(keyId)) {
+            let index = columns.push(listOfFields!.get(keyId)!.key);
+            this.props.Document.SetData(KeyStore.ColumnsKey, columns, ListField);
+        }
+    }
+
+    dropdownItemOnPointerDown = (e: React.PointerEvent): void => {
+        //(e.currentTarget.children[0] as Dropdown.Item ).onSelect();
+    }
+
     render() {
         const columns = this.props.Document.GetList(KeyStore.ColumnsKey, [KeyStore.Title, KeyStore.Data, KeyStore.Author])
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
@@ -205,6 +228,47 @@ export class CollectionSchemaView extends CollectionViewBase {
             <div className="collectionSchemaView-previewHandle" onPointerDown={this.onExpanderDown} />);
         let dividerDragger = this._splitPercentage == 100 ? (null) :
             <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />
+
+        //get the union of all childrens' keys
+        let addFields: { id: string, name: string }[] = [];
+        let removeFields: { id: string, name: string }[] = [];
+        //children.forEach((child) => {
+        //   for (var keyId in fields.keys) {
+        //       if (!allFields.includes(keyId)) {
+        //           allFields.push(keyId);
+        //      }
+        //   }
+        // });
+        let optionsMenu = null;
+        if (this.props.active()) {
+            let protos = this.props.Document.GetAllPrototypes();
+            for (const proto of protos) {
+                proto._proxies.forEach((val, key) => {
+                    if (!(key in addFields.keys)) {
+                        let this_name: string = proto.fields!.get(key)!.key.Name;
+                        addFields.push({ id: key, name: this_name });
+                    }
+                })
+            }
+            optionsMenu = !this.props.active() ? (null) : (<Flyout
+                anchorPoint={anchorPoints.LEFT_TOP}
+                content={<div id="options-flyout-div"> <h5>Options</h5>
+                    <DropdownButton id="dropdown-basic-button" className="colDropDown" title="Add Column">
+                        {addFields.map(({ id, name }) => (
+                            <div className="dd-item-containter"><Dropdown.Item className="dd-item" eventKey={id} onSelect={this.keyDropDownOnSelect}>{name} </Dropdown.Item></div>))}
+                    </DropdownButton>
+                    <DropdownButton id="dropdown-basic-button" className="colDropDown" title="Remove Column">
+                        {addFields.map(({ id, name }) => (
+                            <div className="dd-item-containter"><Dropdown.Item className="dd-item" eventKey={id} onSelect={this.keyDropDownOnSelect}>{name} </Dropdown.Item></div>))}
+                    </DropdownButton>
+                </div>
+                }>
+                <div id="schemaOptionsMenuBtn" />
+            </Flyout>);
+        }
+
+
+
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
                 <div className="collectionSchemaView-dropTarget" onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}>
@@ -239,6 +303,8 @@ export class CollectionSchemaView extends CollectionViewBase {
                         {content}
                     </div>
                     {previewHandle}
+                    {optionsMenu}
+
                 </div>
             </div >
         )
-- 
cgit v1.2.3-70-g09d2


From 670cf766c99a8a5de806fd7d6f1d9e357a55071a Mon Sep 17 00:00:00 2001
From: laurawilsonri <laura_wilson@brown.edu>
Date: Mon, 18 Mar 2019 18:29:10 -0400
Subject: not sure

---
 deploy/index.html                                  |   3 -
 package-lock.json                                  | 419 ++++++++++++++++++---
 package.json                                       |   6 -
 .../views/collections/CollectionSchemaView.tsx     |  80 ++--
 4 files changed, 402 insertions(+), 106 deletions(-)

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

diff --git a/deploy/index.html b/deploy/index.html
index dbfc6dee0..ca5c13e98 100644
--- a/deploy/index.html
+++ b/deploy/index.html
@@ -2,12 +2,9 @@
 
 <head>
   <title>Dash Web</title>
-<<<<<<< HEAD
   <link href="https://fonts.googleapis.com/css?family=Fjalla+One|Hind+Siliguri:300" rel="stylesheet">
   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
     integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
-=======
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
   <script src="https://cdnjs.cloudflare.com/ajax/libs/typescript/3.3.1/typescript.min.js"></script>
 </head>
 
diff --git a/package-lock.json b/package-lock.json
index 3d66773f2..18365bf9b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -152,11 +152,10 @@
       }
     },
     "@hig/theme-context": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@hig/theme-context/-/theme-context-2.1.2.tgz",
-      "integrity": "sha512-JTdYJgJpbPX0KPrjBkeKUFq8fLq7PFmMaBQaT71z6vs/ARqdeYC1ZNpksH2HCzDNU7mjGgFineA9He3eR3sgpg==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@hig/theme-context/-/theme-context-2.1.3.tgz",
+      "integrity": "sha512-c0Ju+Z8C532ZZtjwOLzN+XeO+pL3kqUawu6ZG3J084MH5RM9W8JCKyMf4D9Qr38jFWoiX6u8yiSxxjV/mz9Sqw==",
       "requires": {
-        "@hig/theme-data": "^2.3.2",
         "create-react-context": "^0.2.3",
         "prop-types": "^15.6.1"
       }
@@ -225,6 +224,11 @@
       "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
       "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA=="
     },
+    "@types/async": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/@types/async/-/async-2.4.1.tgz",
+      "integrity": "sha512-C09BK/wXzbW+/JK9zckhe+FeSbg7NmvVjUWwApnw7ksRpUq3ecGLiq2Aw1LlY4Z/VmtdhSaIs7jO5/MWRYMcOA=="
+    },
     "@types/babel-types": {
       "version": "7.0.6",
       "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.6.tgz",
@@ -292,6 +296,22 @@
         "@types/express": "*"
       }
     },
+    "@types/cookie-parser": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.1.tgz",
+      "integrity": "sha512-iJY6B3ZGufLiDf2OCAgiAAQuj1sMKC/wz/7XCEjZ+/MDuultfFJuSwrBKcLSmJ5iYApLzCCYBYJZs0Ws8GPmwA==",
+      "requires": {
+        "@types/express": "*"
+      }
+    },
+    "@types/cookie-session": {
+      "version": "2.0.36",
+      "resolved": "https://registry.npmjs.org/@types/cookie-session/-/cookie-session-2.0.36.tgz",
+      "integrity": "sha512-vnKXnz9vGdOF6Gi9mvaMEtSn2PlDotvde1u9xVzzBRAVsPcufEmDfmas7023T7PpK9Awv1JqQDwN1ThjPSAoTA==",
+      "requires": {
+        "@types/express": "*"
+      }
+    },
     "@types/events": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
@@ -400,6 +420,14 @@
       "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz",
       "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw=="
     },
+    "@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==",
+      "requires": {
+        "mobile-detect": "*"
+      }
+    },
     "@types/mocha": {
       "version": "5.2.6",
       "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.6.tgz",
@@ -429,6 +457,14 @@
       "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.30.tgz",
       "integrity": "sha512-nsqTN6zUcm9xtdJiM9OvOJ5EF0kOI8f1Zuug27O/rgtxCRJHGqncSWfCMZUP852dCKPsDsYXGvBhxfRjDBkF5Q=="
     },
+    "@types/nodemailer": {
+      "version": "4.6.6",
+      "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-4.6.6.tgz",
+      "integrity": "sha512-N2czhXs7fbQhvoquEGzmHAWttnxLfrM3+cWMRFX4hTQq4GE3VyaSE3MOOse4VoNgvtti/H5ow/Hq9KXu/UMWqA==",
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/orderedmap": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@types/orderedmap/-/orderedmap-1.0.0.tgz",
@@ -485,6 +521,15 @@
         "@types/prosemirror-state": "*"
       }
     },
+    "@types/prosemirror-inputrules": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@types/prosemirror-inputrules/-/prosemirror-inputrules-1.0.2.tgz",
+      "integrity": "sha512-bKFneQUPnkZmzCJ1uoitpKH6PFW0hc4q55NsC7mFUCvX0eZl0GRKxyfV47jkJbsbyUQoO/QFv0WwLDz2bo15sA==",
+      "requires": {
+        "@types/prosemirror-model": "*",
+        "@types/prosemirror-state": "*"
+      }
+    },
     "@types/prosemirror-keymap": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/@types/prosemirror-keymap/-/prosemirror-keymap-1.0.1.tgz",
@@ -1160,7 +1205,6 @@
       "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",
@@ -1215,11 +1259,11 @@
       "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk="
     },
     "async": {
-      "version": "2.6.1",
-      "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
-      "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
+      "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
       "requires": {
-        "lodash": "^4.17.10"
+        "lodash": "^4.17.11"
       }
     },
     "async-each": {
@@ -1525,8 +1569,7 @@
     "bn.js": {
       "version": "4.11.8",
       "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
-      "dev": true
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
     },
     "body-parser": {
       "version": "1.18.3",
@@ -1695,8 +1738,7 @@
     "brorand": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
-      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
-      "dev": true
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
     },
     "browser-stdout": {
       "version": "1.3.1",
@@ -1708,7 +1750,6 @@
       "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",
@@ -1722,7 +1763,6 @@
       "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",
@@ -1733,7 +1773,6 @@
       "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",
@@ -1745,7 +1784,6 @@
       "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"
@@ -1755,7 +1793,6 @@
       "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",
@@ -1816,8 +1853,7 @@
     "buffer-xor": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
-      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
-      "dev": true
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
     },
     "builtin-status-codes": {
       "version": "3.0.0",
@@ -2021,7 +2057,6 @@
       "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"
@@ -2359,11 +2394,60 @@
       "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
       "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
     },
+    "cookie-parser": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.4.tgz",
+      "integrity": "sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw==",
+      "requires": {
+        "cookie": "0.3.1",
+        "cookie-signature": "1.0.6"
+      }
+    },
+    "cookie-session": {
+      "version": "2.0.0-beta.3",
+      "resolved": "https://registry.npmjs.org/cookie-session/-/cookie-session-2.0.0-beta.3.tgz",
+      "integrity": "sha512-zyqm5tA0z9yMEB/xyP7lnRnqp8eLR2e0dap+9+rBwVigla9yPKn8XTL1jJymog8xjfrowqW2o5LUjixQChkqrw==",
+      "requires": {
+        "cookies": "0.7.1",
+        "debug": "3.1.0",
+        "on-headers": "~1.0.1",
+        "safe-buffer": "5.1.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "safe-buffer": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+          "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+        }
+      }
+    },
     "cookie-signature": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
       "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
     },
+    "cookies": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.1.tgz",
+      "integrity": "sha1-fIphX1SBxhq58WyDNzG8uPZjuZs=",
+      "requires": {
+        "depd": "~1.1.1",
+        "keygrip": "~1.0.2"
+      }
+    },
     "copy-concurrently": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
@@ -2430,7 +2514,6 @@
       "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"
@@ -2459,7 +2542,6 @@
       "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",
@@ -2472,7 +2554,6 @@
       "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",
@@ -2516,7 +2597,6 @@
       "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",
@@ -2779,7 +2859,6 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
       "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
-      "dev": true,
       "requires": {
         "inherits": "^2.0.1",
         "minimalistic-assert": "^1.0.0"
@@ -2821,7 +2900,6 @@
       "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",
@@ -2954,7 +3032,6 @@
       "version": "6.4.1",
       "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz",
       "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==",
-      "dev": true,
       "requires": {
         "bn.js": "^4.4.0",
         "brorand": "^1.0.1",
@@ -3222,7 +3299,6 @@
       "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"
@@ -4559,6 +4635,21 @@
         "ansi-regex": "^2.0.0"
       }
     },
+    "has-binary": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz",
+      "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=",
+      "requires": {
+        "isarray": "0.0.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+        }
+      }
+    },
     "has-binary2": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
@@ -4628,7 +4719,6 @@
       "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"
@@ -4638,7 +4728,6 @@
       "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"
@@ -4654,7 +4743,6 @@
       "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",
@@ -5365,8 +5453,7 @@
     "json3": {
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
-      "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=",
-      "dev": true
+      "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE="
     },
     "json5": {
       "version": "1.0.1",
@@ -5519,6 +5606,11 @@
       "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz",
       "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ="
     },
+    "keygrip": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.3.tgz",
+      "integrity": "sha512-/PpesirAIfaklxUzp4Yb7xBper9MwP6hNRA6BGGUFCgbJ+BM5CKBtsoxinNXkLHAr+GXS1/lSlF2rP7cv5Fl+g=="
+    },
     "killable": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@@ -5845,7 +5937,6 @@
       "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",
@@ -5940,7 +6031,6 @@
       "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"
@@ -5973,14 +6063,12 @@
     "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==",
-      "dev": true
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
     },
     "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=",
-      "dev": true
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
     },
     "minimatch": {
       "version": "3.0.4",
@@ -6065,6 +6153,11 @@
         }
       }
     },
+    "mobile-detect": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/mobile-detect/-/mobile-detect-1.4.3.tgz",
+      "integrity": "sha512-UaahPNLllQsstHOEHAmVnTHCMQrAS9eL5Qgdi50QrYz6UgGk+Xziz2udz2GN6NYcyODcPLnasC7a7s6R2DjiaQ=="
+    },
     "mobx": {
       "version": "5.9.0",
       "resolved": "https://registry.npmjs.org/mobx/-/mobx-5.9.0.tgz",
@@ -6189,6 +6282,14 @@
         "sliced": "1.0.1"
       },
       "dependencies": {
+        "async": {
+          "version": "2.6.1",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
+          "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
+          "requires": {
+            "lodash": "^4.17.10"
+          }
+        },
         "bson": {
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz",
@@ -6494,6 +6595,11 @@
         }
       }
     },
+    "nodemailer": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-5.1.1.tgz",
+      "integrity": "sha512-hKGCoeNdFL2W7S76J/Oucbw0/qRlfG815tENdhzcqTpSjKgAN91mFOqU2lQUflRRxFM7iZvCyaFcAR9noc/CqQ=="
+    },
     "nodemon": {
       "version": "1.18.10",
       "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.18.10.tgz",
@@ -9750,6 +9856,11 @@
         "is-wsl": "^1.1.0"
       }
     },
+    "options": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
+      "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
+    },
     "orderedmap": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-1.0.0.tgz",
@@ -9868,7 +9979,6 @@
       "version": "5.1.4",
       "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz",
       "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==",
-      "dev": true,
       "requires": {
         "asn1.js": "^4.0.0",
         "browserify-aes": "^1.0.0",
@@ -9893,6 +10003,14 @@
       "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
       "dev": true
     },
+    "parsejson": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz",
+      "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=",
+      "requires": {
+        "better-assert": "~1.0.0"
+      }
+    },
     "parseqs": {
       "version": "0.0.5",
       "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
@@ -10000,7 +10118,6 @@
       "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",
@@ -10433,7 +10550,6 @@
       "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",
@@ -10621,7 +10737,6 @@
       "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"
       }
@@ -10630,7 +10745,6 @@
       "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"
@@ -11344,7 +11458,6 @@
       "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"
@@ -11595,7 +11708,6 @@
       "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"
@@ -11845,6 +11957,204 @@
         }
       }
     },
+    "socketio": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/socketio/-/socketio-1.0.0.tgz",
+      "integrity": "sha1-aOoVmP0kBWFgFxLldJl2ftjrqMo=",
+      "requires": {
+        "express": "^4.13.3",
+        "socket.io": "^1.3.7"
+      },
+      "dependencies": {
+        "accepts": {
+          "version": "1.3.3",
+          "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
+          "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=",
+          "requires": {
+            "mime-types": "~2.1.11",
+            "negotiator": "0.6.1"
+          }
+        },
+        "arraybuffer.slice": {
+          "version": "0.0.6",
+          "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz",
+          "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco="
+        },
+        "blob": {
+          "version": "0.0.4",
+          "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
+          "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE="
+        },
+        "component-emitter": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz",
+          "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM="
+        },
+        "debug": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+          "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+          "requires": {
+            "ms": "0.7.2"
+          }
+        },
+        "engine.io": {
+          "version": "1.8.5",
+          "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.5.tgz",
+          "integrity": "sha512-j1DWIcktw4hRwrv6nWx++5nFH2X64x16MAG2P0Lmi5Dvdfi3I+Jhc7JKJIdAmDJa+5aZ/imHV7dWRPy2Cqjh3A==",
+          "requires": {
+            "accepts": "1.3.3",
+            "base64id": "1.0.0",
+            "cookie": "0.3.1",
+            "debug": "2.3.3",
+            "engine.io-parser": "1.3.2",
+            "ws": "~1.1.5"
+          }
+        },
+        "engine.io-client": {
+          "version": "1.8.5",
+          "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.5.tgz",
+          "integrity": "sha512-AYTgHyeVUPitsseqjoedjhYJapNVoSPShbZ+tEUX9/73jgZ/Z3sUlJf9oYgdEBBdVhupUpUqSxH0kBCXlQnmZg==",
+          "requires": {
+            "component-emitter": "1.2.1",
+            "component-inherit": "0.0.3",
+            "debug": "2.3.3",
+            "engine.io-parser": "1.3.2",
+            "has-cors": "1.1.0",
+            "indexof": "0.0.1",
+            "parsejson": "0.0.3",
+            "parseqs": "0.0.5",
+            "parseuri": "0.0.5",
+            "ws": "~1.1.5",
+            "xmlhttprequest-ssl": "1.5.3",
+            "yeast": "0.1.2"
+          },
+          "dependencies": {
+            "component-emitter": {
+              "version": "1.2.1",
+              "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+              "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
+            }
+          }
+        },
+        "engine.io-parser": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz",
+          "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=",
+          "requires": {
+            "after": "0.8.2",
+            "arraybuffer.slice": "0.0.6",
+            "base64-arraybuffer": "0.1.5",
+            "blob": "0.0.4",
+            "has-binary": "0.1.7",
+            "wtf-8": "1.0.0"
+          }
+        },
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+        },
+        "ms": {
+          "version": "0.7.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+          "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
+        },
+        "object-assign": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz",
+          "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A="
+        },
+        "socket.io": {
+          "version": "1.7.4",
+          "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.4.tgz",
+          "integrity": "sha1-L37O3DORvy1cc+KR/iM+bjTU3QA=",
+          "requires": {
+            "debug": "2.3.3",
+            "engine.io": "~1.8.4",
+            "has-binary": "0.1.7",
+            "object-assign": "4.1.0",
+            "socket.io-adapter": "0.5.0",
+            "socket.io-client": "1.7.4",
+            "socket.io-parser": "2.3.1"
+          }
+        },
+        "socket.io-adapter": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz",
+          "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=",
+          "requires": {
+            "debug": "2.3.3",
+            "socket.io-parser": "2.3.1"
+          }
+        },
+        "socket.io-client": {
+          "version": "1.7.4",
+          "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.4.tgz",
+          "integrity": "sha1-7J+CA1btme9tNX8HVtZIcXvdQoE=",
+          "requires": {
+            "backo2": "1.0.2",
+            "component-bind": "1.0.0",
+            "component-emitter": "1.2.1",
+            "debug": "2.3.3",
+            "engine.io-client": "~1.8.4",
+            "has-binary": "0.1.7",
+            "indexof": "0.0.1",
+            "object-component": "0.0.3",
+            "parseuri": "0.0.5",
+            "socket.io-parser": "2.3.1",
+            "to-array": "0.1.4"
+          },
+          "dependencies": {
+            "component-emitter": {
+              "version": "1.2.1",
+              "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+              "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
+            }
+          }
+        },
+        "socket.io-parser": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz",
+          "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=",
+          "requires": {
+            "component-emitter": "1.1.2",
+            "debug": "2.2.0",
+            "isarray": "0.0.1",
+            "json3": "3.3.2"
+          },
+          "dependencies": {
+            "debug": {
+              "version": "2.2.0",
+              "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+              "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+              "requires": {
+                "ms": "0.7.1"
+              }
+            },
+            "ms": {
+              "version": "0.7.1",
+              "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+              "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg="
+            }
+          }
+        },
+        "ws": {
+          "version": "1.1.5",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz",
+          "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==",
+          "requires": {
+            "options": ">=0.0.5",
+            "ultron": "1.0.x"
+          }
+        },
+        "xmlhttprequest-ssl": {
+          "version": "1.5.3",
+          "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz",
+          "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0="
+        }
+      }
+    },
     "sockjs": {
       "version": "0.3.19",
       "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
@@ -12745,6 +13055,11 @@
         "random-bytes": "~1.0.0"
       }
     },
+    "ultron": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
+      "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po="
+    },
     "uncontrollable": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-6.1.0.tgz",
@@ -13884,6 +14199,11 @@
         "async-limiter": "~1.0.0"
       }
     },
+    "wtf-8": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz",
+      "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo="
+    },
     "xdg-basedir": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
@@ -13894,6 +14214,11 @@
       "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
       "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
     },
+    "xoauth2": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/xoauth2/-/xoauth2-1.2.0.tgz",
+      "integrity": "sha1-8u76wRRyyXHqO8RuVU60sSMhRuU="
+    },
     "xregexp": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz",
diff --git a/package.json b/package.json
index 640f16437..a4a328859 100644
--- a/package.json
+++ b/package.json
@@ -38,13 +38,10 @@
     "@fortawesome/free-solid-svg-icons": "^5.7.2",
     "@fortawesome/react-fontawesome": "^0.1.4",
     "@hig/flyout": "^1.0.3",
-<<<<<<< HEAD
     "@trendmicro/react-dropdown": "^1.3.0",
-=======
     "@types/async": "^2.4.1",
     "@hig/theme-context": "^2.1.3",
     "@hig/theme-data": "^2.3.3",
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
     "@types/bcrypt-nodejs": "0.0.30",
     "@types/bluebird": "^3.5.25",
     "@types/body-parser": "^1.17.0",
@@ -92,11 +89,8 @@
     "bcrypt-nodejs": "0.0.3",
     "bluebird": "^3.5.3",
     "body-parser": "^1.18.3",
-<<<<<<< HEAD
     "bootstrap": "^4.3.1",
-=======
     "connect-flash": "^0.1.1",
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
     "connect-mongo": "^2.0.3",
     "cookie-parser": "^1.4.4",
     "cookie-session": "^2.0.0-beta.3",
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 2598dd3a9..da38d54c4 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,10 +1,5 @@
-<<<<<<< HEAD
-import React = require("react");
-import { action, observable } from "mobx";
-=======
 import React = require("react")
 import { action, observable, ObservableMap, computed } from "mobx";
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
 import { observer } from "mobx-react";
 import Measure from "react-measure";
 import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
@@ -22,23 +17,13 @@ import "./CollectionSchemaView.scss";
 import { COLLECTION_BORDER_WIDTH, CollectionView } from "./CollectionView";
 import { CollectionViewBase } from "./CollectionViewBase";
 import { setupDrag } from "../../util/DragManager";
-<<<<<<< HEAD
 import '../DocumentDecorations.scss';
 import { Flyout, anchorPoints } from "../DocumentDecorations";
 import { DropdownButton, Dropdown } from 'react-bootstrap';
 import { ListField } from "../../../fields/ListField";
 import { Key } from "../../../fields/Key";
-//import { Server } from "http";
-//import { Server } from "http";
 import { Server } from "../../Server";
 
-//import { MenuItem } from 'react-bootstrap';
-=======
-import { Key } from "./../../../fields/Key";
-import { Server } from "../../Server";
-import { ListField } from "../../../fields/ListField";
-
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
 
 // bcz: need to add drag and drop of rows and columns.  This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
 
@@ -349,18 +334,10 @@ export class CollectionSchemaView extends CollectionViewBase {
             <div className="collectionSchemaView-columnsHandle" onPointerDown={this.onColumnsDown} />);
         let dividerDragger = this.splitPercentage == 0 ? (null) :
             <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />
-<<<<<<< HEAD
 
         //get the union of all childrens' keys
         let addFields: { id: string, name: string }[] = [];
         let removeFields: { id: string, name: string }[] = [];
-        //children.forEach((child) => {
-        //   for (var keyId in fields.keys) {
-        //       if (!allFields.includes(keyId)) {
-        //           allFields.push(keyId);
-        //      }
-        //   }
-        // });
         let optionsMenu = null;
         if (this.props.active()) {
             let protos = this.props.Document.GetAllPrototypes();
@@ -372,28 +349,32 @@ export class CollectionSchemaView extends CollectionViewBase {
                     }
                 })
             }
-            optionsMenu = !this.props.active() ? (null) : (<Flyout
-                anchorPoint={anchorPoints.LEFT_TOP}
-                content={<div id="options-flyout-div"> <h5>Options</h5>
-                    <DropdownButton id="dropdown-basic-button" className="colDropDown" title="Add Column">
+            /*<DropdownButton id="dropdown-basic-button" className="colDropDown" title="Add Column">
                         {addFields.map(({ id, name }) => (
                             <div className="dd-item-containter"><Dropdown.Item className="dd-item" eventKey={id} onSelect={this.keyDropDownOnSelect}>{name} </Dropdown.Item></div>))}
                     </DropdownButton>
                     <DropdownButton id="dropdown-basic-button" className="colDropDown" title="Remove Column">
                         {addFields.map(({ id, name }) => (
                             <div className="dd-item-containter"><Dropdown.Item className="dd-item" eventKey={id} onSelect={this.keyDropDownOnSelect}>{name} </Dropdown.Item></div>))}
-                    </DropdownButton>
+                    </DropdownButton>*/
+            optionsMenu = !this.props.active() ? (null) : (<Flyout
+                anchorPoint={anchorPoints.LEFT_TOP}
+                content={<div id="options-flyout-div"> <h5>Options</h5>
+                    <div className="addColumn-options">
+                        <ul style={{ overflow: "scroll" }}>
+                            {Array.from(Object.keys(allKeys)).map(item => {
+                                return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
+                            })}
+                        </ul>
+                    </div>
                 </div>
                 }>
                 <div id="schemaOptionsMenuBtn" />
             </Flyout>);
         }
 
-
-=======
         let colDividerDragger = this._columnsPercentage == 0 ? (null) :
             <div className="collectionSchemaView-colDividerDragger" onPointerDown={this.onColDividerDown} style={{ height: `${this.DIVIDER_WIDTH}px` }} />
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
 
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
@@ -424,19 +405,6 @@ export class CollectionSchemaView extends CollectionViewBase {
                                         getTrProps={this.getTrProps}
                                     />
                                 </div>
-                                {colDividerDragger}
-                                <div className="collectionSchemaView-addColumn" style={{ height: `${this._columnsPercentage}%` }} >
-                                    {/* <input type="checkbox" id="addColumn-toggle" />
-                                    <label htmlFor="addColumn-toggle" title="Add Column"><p>+</p></label> */}
-
-                                    <div className="addColumn-options">
-                                        <ul style={{ overflow: "scroll" }}>
-                                            {Array.from(Object.keys(allKeys)).map(item => {
-                                                return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
-                                            })}
-                                        </ul>
-                                    </div>
-                                </div>
                             </div>
                         }
                     </Measure>
@@ -445,14 +413,26 @@ export class CollectionSchemaView extends CollectionViewBase {
                         {content}
                     </div>
                     {previewHandle}
-<<<<<<< HEAD
-                    {optionsMenu}
-=======
-                    {columnsHandle}
->>>>>>> f70ad315167b714f11f7d68f35a46abe9e525a4d
 
+                    {columnsHandle}
+                    {optionsMenu}
                 </div>
             </div >
         )
     }
-}
\ No newline at end of file
+}
+/*
+{colDividerDragger}
+                                <div className="collectionSchemaView-addColumn" style={{ height: `${this._columnsPercentage}%` }} >
+                                    {/* <input type="checkbox" id="addColumn-toggle" />
+                                    <label htmlFor="addColumn-toggle" title="Add Column"><p>+</p></label> }
+
+                                    <div className="addColumn-options">
+                                        <ul style={{ overflow: "scroll" }}>
+                                            {Array.from(Object.keys(allKeys)).map(item => {
+                                                return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
+                                            })}
+                                        </ul>
+                                    </div>
+                                </div>
+                                */
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 5e416c352ebfb875482f890c6362fee5f84af1f6 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 19 Mar 2019 15:50:54 -0400
Subject: started to integrate Northstar.  changed server port to 4321.

---
 deploy/assets/env.json                             |   15 +
 package.json                                       |    3 +-
 src/client/Server.ts                               |    2 +-
 src/client/northstar/manager/Gateway.ts            |  269 +
 .../northstar/model/idea/MetricTypeMapping.ts      |   30 +
 src/client/northstar/model/idea/idea.ts            | 8551 ++++++++++++++++++++
 src/client/views/Main.tsx                          |   28 +-
 .../views/collections/CollectionSchemaView.tsx     |    4 +-
 src/server/index.ts                                |    2 +-
 webpack.config.js                                  |    2 +-
 10 files changed, 8896 insertions(+), 10 deletions(-)
 create mode 100644 deploy/assets/env.json
 create mode 100644 src/client/northstar/manager/Gateway.ts
 create mode 100644 src/client/northstar/model/idea/MetricTypeMapping.ts
 create mode 100644 src/client/northstar/model/idea/idea.ts

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

diff --git a/deploy/assets/env.json b/deploy/assets/env.json
new file mode 100644
index 000000000..80963ea0d
--- /dev/null
+++ b/deploy/assets/env.json
@@ -0,0 +1,15 @@
+{
+    "IS_DARPA": false,
+    "IS_IGT": false,
+    "IS_MENU_FIXED": true,
+    "SERVER_URL": "http://localhost:1234",
+    "SERVER_API_PATH": "api",
+    "SAMPLE_SIZE": 100000,
+    "X_BINS": 15,
+    "Y_BINS": 15,
+    "SPLASH_TIME_IN_MS": 0,
+    "SHOW_FPS_COUNTER": true,
+    "SHOW_SHUTDOWN_BUTTON": false,
+    "DEGREE_OF_PARALLISM": 1,
+    "SHOW_WARNINGS": false
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 7ed94c508..c87e31bc4 100644
--- a/package.json
+++ b/package.json
@@ -38,9 +38,9 @@
     "@fortawesome/free-solid-svg-icons": "^5.7.2",
     "@fortawesome/react-fontawesome": "^0.1.4",
     "@hig/flyout": "^1.0.3",
-    "@types/async": "^2.4.1",
     "@hig/theme-context": "^2.1.3",
     "@hig/theme-data": "^2.3.3",
+    "@types/async": "^2.4.1",
     "@types/bcrypt-nodejs": "0.0.30",
     "@types/bluebird": "^3.5.25",
     "@types/body-parser": "^1.17.0",
@@ -149,6 +149,7 @@
     "socket.io": "^2.2.0",
     "socket.io-client": "^2.2.0",
     "socketio": "^1.0.0",
+    "typescript-collections": "^1.3.2",
     "url-loader": "^1.1.2",
     "uuid": "^3.3.2",
     "xoauth2": "^1.2.0"
diff --git a/src/client/Server.ts b/src/client/Server.ts
index 3fb1ae878..bbdc27397 100644
--- a/src/client/Server.ts
+++ b/src/client/Server.ts
@@ -9,7 +9,7 @@ import { MessageStore, Types } from "./../server/Message";
 
 export class Server {
     public static ClientFieldsCached: ObservableMap<FieldId, Field | FIELD_WAITING> = new ObservableMap();
-    static Socket: SocketIOClient.Socket = OpenSocket(`${window.location.protocol}//${window.location.hostname}:1234`);
+    static Socket: SocketIOClient.Socket = OpenSocket(`${window.location.protocol}//${window.location.hostname}:4321`);
     static GUID: string = Utils.GenerateGuid()
 
 
diff --git a/src/client/northstar/manager/Gateway.ts b/src/client/northstar/manager/Gateway.ts
new file mode 100644
index 000000000..5ae5e4f47
--- /dev/null
+++ b/src/client/northstar/manager/Gateway.ts
@@ -0,0 +1,269 @@
+import { Catalog, OperationReference, Result, CompileResults } from "../model/idea/idea"
+import { computed, observable, action } from "mobx";
+
+export class Gateway {
+
+    private static _instance: Gateway;
+
+    private constructor() {
+    }
+
+    public static get Instance() {
+        return this._instance || (this._instance = new this());
+    }
+
+    public async GetCatalog(): Promise<Catalog> {
+        try {
+            const json = await this.MakeGetRequest("catalog");
+            const cat = Catalog.fromJS(json);
+            return cat;
+        }
+        catch (error) {
+            throw new Error("can not reach northstar's backend");
+        }
+    }
+
+    public async ClearCatalog(): Promise<void> {
+        try {
+            const json = await this.MakePostJsonRequest("Datamart/ClearAllAugmentations", {});
+        }
+        catch (error) {
+            throw new Error("can not reach northstar's backend");
+        }
+    }
+
+    public async TerminateServer(): Promise<void> {
+        try {
+            const url = Gateway.ConstructUrl("terminateServer");
+            const response = await fetch(url,
+                {
+                    redirect: "follow",
+                    method: "POST",
+                    credentials: "include"
+                });
+        }
+        catch (error) {
+            throw new Error("can not reach northstar's backend");
+        }
+    }
+
+    public async Compile(data: any): Promise<CompileResults | undefined> {
+        const json = await this.MakePostJsonRequest("compile", data);
+        if (json != null) {
+            const cr = CompileResults.fromJS(json);
+            return cr;
+        }
+    }
+
+    public async SubmitResult(data: any): Promise<void> {
+        try {
+            console.log(data);
+            const url = Gateway.ConstructUrl("submitProblem");
+            const response = await fetch(url,
+                {
+                    redirect: "follow",
+                    method: "POST",
+                    credentials: "include",
+                    body: JSON.stringify(data)
+                });
+        }
+        catch (error) {
+            throw new Error("can not reach northstar's backend");
+        }
+    }
+
+    public async SpecifyProblem(data: any): Promise<void> {
+        try {
+            console.log(data);
+            const url = Gateway.ConstructUrl("specifyProblem");
+            const response = await fetch(url,
+                {
+                    redirect: "follow",
+                    method: "POST",
+                    credentials: "include",
+                    body: JSON.stringify(data)
+                });
+        }
+        catch (error) {
+            throw new Error("can not reach northstar's backend");
+        }
+    }
+
+    public async ExportToScript(solutionId: string): Promise<string> {
+        try {
+            const url = Gateway.ConstructUrl("exportsolution/script/" + solutionId);
+            const response = await fetch(url,
+                {
+                    redirect: "follow",
+                    method: "GET",
+                    credentials: "include"
+                });
+            return await response.text();
+        }
+        catch (error) {
+            throw new Error("can not reach northstar's backend");
+        }
+    }
+
+
+    public async StartOperation(data: any): Promise<OperationReference | undefined> {
+        const json = await this.MakePostJsonRequest("operation", data);
+        if (json != null) {
+            const or = OperationReference.fromJS(json);
+            return or;
+        }
+    }
+
+    public async GetResult(data: any): Promise<Result | undefined> {
+        const json = await this.MakePostJsonRequest("result", data);
+        if (json != null) {
+            const res = Result.fromJS(json);
+            return res;
+        }
+    }
+
+    public async PauseOperation(data: any): Promise<void> {
+        const url = Gateway.ConstructUrl("pause");
+        await fetch(url,
+            {
+                redirect: "follow",
+                method: "POST",
+                credentials: "include",
+                body: JSON.stringify(data)
+            });
+    }
+
+    public async MakeGetRequest(endpoint: string, signal?: AbortSignal): Promise<any> {
+        const url = Gateway.ConstructUrl(endpoint);
+        const response = await fetch(url,
+            {
+                redirect: "follow",
+                method: "GET",
+                credentials: "include",
+                signal
+            });
+        const json = await response.json();
+        return json;
+    }
+
+    public async MakePostJsonRequest(endpoint: string, data: any, signal?: AbortSignal): Promise<any> {
+        const url = Gateway.ConstructUrl(endpoint);
+        const response = await fetch(url,
+            {
+                redirect: "follow",
+                method: "POST",
+                credentials: "include",
+                body: JSON.stringify(data),
+                signal
+            });
+        const json = await response.json();
+        return json;
+    }
+
+
+    public static ConstructUrl(appendix: string): string {
+        let base = Settings.Instance.ServerUrl;
+        if (base.slice(-1) == "/") {
+            base = base.slice(0, -1);
+        }
+        let url = base + "/" + Settings.Instance.ServerApiPath + "/" + appendix;
+        return url;
+    }
+}
+
+declare var ENV: any;
+
+export class Settings {
+    private _environment: any;
+
+    @observable
+    public ServerUrl: string = document.URL;
+
+    @observable
+    public ServerApiPath?: string;
+
+    @observable
+    public SampleSize?: number;
+
+    @observable
+    public XBins?: number;
+
+    @observable
+    public YBins?: number;
+
+    @observable
+    public SplashTimeInMS?: number;
+
+    @observable
+    public ShowFpsCounter?: boolean;
+
+    @observable
+    public IsMenuFixed?: boolean;
+
+    @observable
+    public ShowShutdownButton?: boolean;
+
+    @observable
+    public IsDarpa?: boolean;
+
+    @observable
+    public IsIGT?: boolean;
+
+    @observable
+    public DegreeOfParallelism?: number;
+
+    @observable
+    public ShowWarnings?: boolean;
+
+    @computed
+    public get IsDev(): boolean {
+        return ENV.IsDev;
+    }
+
+    @computed
+    public get TestDataFolderPath(): string {
+        return this.Origin + "testdata/";
+    }
+
+    @computed
+    public get Origin(): string {
+        return window.location.origin + "/";
+    }
+
+    private static _instance: Settings;
+
+    @action
+    public Update(environment: any): void {
+        /*let serverParam = new URL(document.URL).searchParams.get("serverUrl");
+        if (serverParam) {
+            if (serverParam === "debug") {
+                this.ServerUrl = `http://${window.location.hostname}:1234`;
+            }
+            else {
+                this.ServerUrl = serverParam;
+            }
+        }
+        else {
+            this.ServerUrl = environment["SERVER_URL"] ? environment["SERVER_URL"] : document.URL;
+        }*/
+        this.ServerUrl = environment["SERVER_URL"] ? environment["SERVER_URL"] : document.URL;
+        this.ServerApiPath = environment["SERVER_API_PATH"];
+        this.SampleSize = environment["SAMPLE_SIZE"];
+        this.XBins = environment["X_BINS"];
+        this.YBins = environment["Y_BINS"];
+        this.SplashTimeInMS = environment["SPLASH_TIME_IN_MS"];
+        this.ShowFpsCounter = environment["SHOW_FPS_COUNTER"];
+        this.ShowShutdownButton = environment["SHOW_SHUTDOWN_BUTTON"];
+        this.IsMenuFixed = environment["IS_MENU_FIXED"];
+        this.IsDarpa = environment["IS_DARPA"];
+        this.IsIGT = environment["IS_IGT"];
+        this.DegreeOfParallelism = environment["DEGREE_OF_PARALLISM"];
+    }
+
+    public static get Instance(): Settings {
+        if (!this._instance) {
+            this._instance = new Settings();
+        }
+        return this._instance;
+    }
+}
diff --git a/src/client/northstar/model/idea/MetricTypeMapping.ts b/src/client/northstar/model/idea/MetricTypeMapping.ts
new file mode 100644
index 000000000..11e0c871a
--- /dev/null
+++ b/src/client/northstar/model/idea/MetricTypeMapping.ts
@@ -0,0 +1,30 @@
+import { MetricType } from "./Idea";
+import { Dictionary } from 'typescript-collections';
+
+
+export class MetricTypeMapping {
+
+    public static GetMetricInterpretation(metricType: MetricType): MetricInterpretation {
+        if (metricType == MetricType.Accuracy ||
+            metricType == MetricType.F1 ||
+            metricType == MetricType.F1Macro ||
+            metricType == MetricType.F1Micro ||
+            metricType == MetricType.JaccardSimilarityScore ||
+            metricType == MetricType.ObjectDetectionAveragePrecision ||
+            metricType == MetricType.Precision ||
+            metricType == MetricType.PrecisionAtTopK ||
+            metricType == MetricType.NormalizedMutualInformation ||
+            metricType == MetricType.Recall ||
+            metricType == MetricType.RocAucMacro ||
+            metricType == MetricType.RocAuc ||
+            metricType == MetricType.RocAucMicro ||
+            metricType == MetricType.RSquared) {
+            return MetricInterpretation.HigherIsBetter;
+        }
+        return MetricInterpretation.LowerIsBetter;
+    }
+}
+
+export enum MetricInterpretation {
+    HigherIsBetter, LowerIsBetter
+}
\ No newline at end of file
diff --git a/src/client/northstar/model/idea/idea.ts b/src/client/northstar/model/idea/idea.ts
new file mode 100644
index 000000000..9d9d60678
--- /dev/null
+++ b/src/client/northstar/model/idea/idea.ts
@@ -0,0 +1,8551 @@
+/* tslint:disable */
+//----------------------
+// <auto-generated>
+//     Generated using the NSwag toolchain v11.19.2.0 (NJsonSchema v9.10.73.0 (Newtonsoft.Json v9.0.0.0)) (http://NSwag.org)
+// </auto-generated>
+//----------------------
+// ReSharper disable InconsistentNaming
+
+
+
+export enum AggregateFunction {
+    None = "None",
+    Sum = "Sum",
+    SumE = "SumE",
+    Count = "Count",
+    Min = "Min",
+    Max = "Max",
+    Avg = "Avg",
+}
+
+export abstract class AggregateParameters implements IAggregateParameters {
+
+    protected _discriminator: string;
+
+    constructor(data?: IAggregateParameters) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+        this._discriminator = "AggregateParameters";
+    }
+
+    init(data?: any) {
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): AggregateParameters {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "AverageAggregateParameters") {
+            let result = new AverageAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "SingleDimensionAggregateParameters") {
+            throw new Error("The abstract class 'SingleDimensionAggregateParameters' cannot be instantiated.");
+        }
+        if (data["discriminator"] === "CountAggregateParameters") {
+            let result = new CountAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "KDEAggregateParameters") {
+            let result = new KDEAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "MarginAggregateParameters") {
+            let result = new MarginAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "MaxAggregateParameters") {
+            let result = new MaxAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "MinAggregateParameters") {
+            let result = new MinAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "SumAggregateParameters") {
+            let result = new SumAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "SumEstimationAggregateParameters") {
+            let result = new SumEstimationAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'AggregateParameters' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        return data;
+    }
+}
+
+export interface IAggregateParameters {
+}
+
+export abstract class SingleDimensionAggregateParameters extends AggregateParameters implements ISingleDimensionAggregateParameters {
+    attributeParameters?: AttributeParameters | undefined;
+    distinctAttributeParameters?: AttributeParameters | undefined;
+
+    constructor(data?: ISingleDimensionAggregateParameters) {
+        super(data);
+        this._discriminator = "SingleDimensionAggregateParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.attributeParameters = data["AttributeParameters"] ? AttributeParameters.fromJS(data["AttributeParameters"]) : <any>undefined;
+            this.distinctAttributeParameters = data["DistinctAttributeParameters"] ? AttributeParameters.fromJS(data["DistinctAttributeParameters"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): SingleDimensionAggregateParameters {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "AverageAggregateParameters") {
+            let result = new AverageAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "CountAggregateParameters") {
+            let result = new CountAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "KDEAggregateParameters") {
+            let result = new KDEAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "MarginAggregateParameters") {
+            let result = new MarginAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "MaxAggregateParameters") {
+            let result = new MaxAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "MinAggregateParameters") {
+            let result = new MinAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "SumAggregateParameters") {
+            let result = new SumAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "SumEstimationAggregateParameters") {
+            let result = new SumEstimationAggregateParameters();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'SingleDimensionAggregateParameters' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["AttributeParameters"] = this.attributeParameters ? this.attributeParameters.toJSON() : <any>undefined;
+        data["DistinctAttributeParameters"] = this.distinctAttributeParameters ? this.distinctAttributeParameters.toJSON() : <any>undefined;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ISingleDimensionAggregateParameters extends IAggregateParameters {
+    attributeParameters?: AttributeParameters | undefined;
+    distinctAttributeParameters?: AttributeParameters | undefined;
+}
+
+export class AverageAggregateParameters extends SingleDimensionAggregateParameters implements IAverageAggregateParameters {
+
+    constructor(data?: IAverageAggregateParameters) {
+        super(data);
+        this._discriminator = "AverageAggregateParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): AverageAggregateParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new AverageAggregateParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IAverageAggregateParameters extends ISingleDimensionAggregateParameters {
+}
+
+export abstract class AttributeParameters implements IAttributeParameters {
+    visualizationHints?: VisualizationHint[] | undefined;
+    rawName?: string | undefined;
+
+    protected _discriminator: string;
+
+    constructor(data?: IAttributeParameters) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+        this._discriminator = "AttributeParameters";
+    }
+
+    init(data?: any) {
+        if (data) {
+            if (data["VisualizationHints"] && data["VisualizationHints"].constructor === Array) {
+                this.visualizationHints = [];
+                for (let item of data["VisualizationHints"])
+                    this.visualizationHints.push(item);
+            }
+            this.rawName = data["RawName"];
+        }
+    }
+
+    static fromJS(data: any): AttributeParameters {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "AttributeBackendParameters") {
+            let result = new AttributeBackendParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "AttributeCaclculatedParameters") {
+            throw new Error("The abstract class 'AttributeCaclculatedParameters' cannot be instantiated.");
+        }
+        if (data["discriminator"] === "AttributeCodeParameters") {
+            let result = new AttributeCodeParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "AttributeColumnParameters") {
+            let result = new AttributeColumnParameters();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'AttributeParameters' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        if (this.visualizationHints && this.visualizationHints.constructor === Array) {
+            data["VisualizationHints"] = [];
+            for (let item of this.visualizationHints)
+                data["VisualizationHints"].push(item);
+        }
+        data["RawName"] = this.rawName;
+        return data;
+    }
+}
+
+export interface IAttributeParameters {
+    visualizationHints?: VisualizationHint[] | undefined;
+    rawName?: string | undefined;
+}
+
+export enum VisualizationHint {
+    TreatAsEnumeration = "TreatAsEnumeration",
+    DefaultFlipAxis = "DefaultFlipAxis",
+    Image = "Image",
+}
+
+export abstract class AttributeCaclculatedParameters extends AttributeParameters implements IAttributeCaclculatedParameters {
+
+    constructor(data?: IAttributeCaclculatedParameters) {
+        super(data);
+        this._discriminator = "AttributeCaclculatedParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): AttributeCaclculatedParameters {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "AttributeBackendParameters") {
+            let result = new AttributeBackendParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "AttributeCodeParameters") {
+            let result = new AttributeCodeParameters();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'AttributeCaclculatedParameters' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IAttributeCaclculatedParameters extends IAttributeParameters {
+}
+
+export class AttributeBackendParameters extends AttributeCaclculatedParameters implements IAttributeBackendParameters {
+    id?: string | undefined;
+
+    constructor(data?: IAttributeBackendParameters) {
+        super(data);
+        this._discriminator = "AttributeBackendParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.id = data["Id"];
+        }
+    }
+
+    static fromJS(data: any): AttributeBackendParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new AttributeBackendParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Id"] = this.id;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IAttributeBackendParameters extends IAttributeCaclculatedParameters {
+    id?: string | undefined;
+}
+
+export class AttributeCodeParameters extends AttributeCaclculatedParameters implements IAttributeCodeParameters {
+    code?: string | undefined;
+
+    constructor(data?: IAttributeCodeParameters) {
+        super(data);
+        this._discriminator = "AttributeCodeParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.code = data["Code"];
+        }
+    }
+
+    static fromJS(data: any): AttributeCodeParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new AttributeCodeParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Code"] = this.code;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IAttributeCodeParameters extends IAttributeCaclculatedParameters {
+    code?: string | undefined;
+}
+
+export class AttributeColumnParameters extends AttributeParameters implements IAttributeColumnParameters {
+
+    constructor(data?: IAttributeColumnParameters) {
+        super(data);
+        this._discriminator = "AttributeColumnParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): AttributeColumnParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new AttributeColumnParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IAttributeColumnParameters extends IAttributeParameters {
+}
+
+export class CountAggregateParameters extends SingleDimensionAggregateParameters implements ICountAggregateParameters {
+
+    constructor(data?: ICountAggregateParameters) {
+        super(data);
+        this._discriminator = "CountAggregateParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): CountAggregateParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new CountAggregateParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ICountAggregateParameters extends ISingleDimensionAggregateParameters {
+}
+
+export class KDEAggregateParameters extends SingleDimensionAggregateParameters implements IKDEAggregateParameters {
+    nrOfSamples?: number | undefined;
+
+    constructor(data?: IKDEAggregateParameters) {
+        super(data);
+        this._discriminator = "KDEAggregateParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.nrOfSamples = data["NrOfSamples"];
+        }
+    }
+
+    static fromJS(data: any): KDEAggregateParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new KDEAggregateParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["NrOfSamples"] = this.nrOfSamples;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IKDEAggregateParameters extends ISingleDimensionAggregateParameters {
+    nrOfSamples?: number | undefined;
+}
+
+export class MarginAggregateParameters extends SingleDimensionAggregateParameters implements IMarginAggregateParameters {
+    aggregateFunction?: AggregateFunction | undefined;
+
+    constructor(data?: IMarginAggregateParameters) {
+        super(data);
+        this._discriminator = "MarginAggregateParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.aggregateFunction = data["AggregateFunction"];
+        }
+    }
+
+    static fromJS(data: any): MarginAggregateParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new MarginAggregateParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["AggregateFunction"] = this.aggregateFunction;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IMarginAggregateParameters extends ISingleDimensionAggregateParameters {
+    aggregateFunction?: AggregateFunction | undefined;
+}
+
+export class MaxAggregateParameters extends SingleDimensionAggregateParameters implements IMaxAggregateParameters {
+
+    constructor(data?: IMaxAggregateParameters) {
+        super(data);
+        this._discriminator = "MaxAggregateParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): MaxAggregateParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new MaxAggregateParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IMaxAggregateParameters extends ISingleDimensionAggregateParameters {
+}
+
+export class MinAggregateParameters extends SingleDimensionAggregateParameters implements IMinAggregateParameters {
+
+    constructor(data?: IMinAggregateParameters) {
+        super(data);
+        this._discriminator = "MinAggregateParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): MinAggregateParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new MinAggregateParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IMinAggregateParameters extends ISingleDimensionAggregateParameters {
+}
+
+export class SumAggregateParameters extends SingleDimensionAggregateParameters implements ISumAggregateParameters {
+
+    constructor(data?: ISumAggregateParameters) {
+        super(data);
+        this._discriminator = "SumAggregateParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): SumAggregateParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new SumAggregateParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ISumAggregateParameters extends ISingleDimensionAggregateParameters {
+}
+
+export class SumEstimationAggregateParameters extends SingleDimensionAggregateParameters implements ISumEstimationAggregateParameters {
+
+    constructor(data?: ISumEstimationAggregateParameters) {
+        super(data);
+        this._discriminator = "SumEstimationAggregateParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): SumEstimationAggregateParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new SumEstimationAggregateParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ISumEstimationAggregateParameters extends ISingleDimensionAggregateParameters {
+}
+
+export enum OrderingFunction {
+    None = 0,
+    SortUp = 1,
+    SortDown = 2,
+}
+
+export abstract class BinningParameters implements IBinningParameters {
+    attributeParameters?: AttributeParameters | undefined;
+
+    protected _discriminator: string;
+
+    constructor(data?: IBinningParameters) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+        this._discriminator = "BinningParameters";
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.attributeParameters = data["AttributeParameters"] ? AttributeParameters.fromJS(data["AttributeParameters"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): BinningParameters {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "EquiWidthBinningParameters") {
+            let result = new EquiWidthBinningParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "SingleBinBinningParameters") {
+            let result = new SingleBinBinningParameters();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'BinningParameters' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        data["AttributeParameters"] = this.attributeParameters ? this.attributeParameters.toJSON() : <any>undefined;
+        return data;
+    }
+}
+
+export interface IBinningParameters {
+    attributeParameters?: AttributeParameters | undefined;
+}
+
+export class EquiWidthBinningParameters extends BinningParameters implements IEquiWidthBinningParameters {
+    minValue?: number | undefined;
+    maxValue?: number | undefined;
+    requestedNrOfBins?: number | undefined;
+    referenceValue?: number | undefined;
+    step?: number | undefined;
+
+    constructor(data?: IEquiWidthBinningParameters) {
+        super(data);
+        this._discriminator = "EquiWidthBinningParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.minValue = data["MinValue"];
+            this.maxValue = data["MaxValue"];
+            this.requestedNrOfBins = data["RequestedNrOfBins"];
+            this.referenceValue = data["ReferenceValue"];
+            this.step = data["Step"];
+        }
+    }
+
+    static fromJS(data: any): EquiWidthBinningParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new EquiWidthBinningParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["MinValue"] = this.minValue;
+        data["MaxValue"] = this.maxValue;
+        data["RequestedNrOfBins"] = this.requestedNrOfBins;
+        data["ReferenceValue"] = this.referenceValue;
+        data["Step"] = this.step;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IEquiWidthBinningParameters extends IBinningParameters {
+    minValue?: number | undefined;
+    maxValue?: number | undefined;
+    requestedNrOfBins?: number | undefined;
+    referenceValue?: number | undefined;
+    step?: number | undefined;
+}
+
+export class SingleBinBinningParameters extends BinningParameters implements ISingleBinBinningParameters {
+
+    constructor(data?: ISingleBinBinningParameters) {
+        super(data);
+        this._discriminator = "SingleBinBinningParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): SingleBinBinningParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new SingleBinBinningParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ISingleBinBinningParameters extends IBinningParameters {
+}
+
+export class Attribute implements IAttribute {
+    displayName?: string | undefined;
+    rawName?: string | undefined;
+    description?: string | undefined;
+    dataType?: DataType | undefined;
+    visualizationHints?: VisualizationHint[] | undefined;
+    isTarget?: boolean | undefined;
+
+    constructor(data?: IAttribute) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.displayName = data["DisplayName"];
+            this.rawName = data["RawName"];
+            this.description = data["Description"];
+            this.dataType = data["DataType"];
+            if (data["VisualizationHints"] && data["VisualizationHints"].constructor === Array) {
+                this.visualizationHints = [];
+                for (let item of data["VisualizationHints"])
+                    this.visualizationHints.push(item);
+            }
+            this.isTarget = data["IsTarget"];
+        }
+    }
+
+    static fromJS(data: any): Attribute {
+        data = typeof data === 'object' ? data : {};
+        let result = new Attribute();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["DisplayName"] = this.displayName;
+        data["RawName"] = this.rawName;
+        data["Description"] = this.description;
+        data["DataType"] = this.dataType;
+        if (this.visualizationHints && this.visualizationHints.constructor === Array) {
+            data["VisualizationHints"] = [];
+            for (let item of this.visualizationHints)
+                data["VisualizationHints"].push(item);
+        }
+        data["IsTarget"] = this.isTarget;
+        return data;
+    }
+}
+
+export interface IAttribute {
+    displayName?: string | undefined;
+    rawName?: string | undefined;
+    description?: string | undefined;
+    dataType?: DataType | undefined;
+    visualizationHints?: VisualizationHint[] | undefined;
+    isTarget?: boolean | undefined;
+}
+
+export enum DataType {
+    Int = "Int",
+    String = "String",
+    Float = "Float",
+    Double = "Double",
+    DateTime = "DateTime",
+    Object = "Object",
+    Undefined = "Undefined",
+}
+
+export class AttributeGroup implements IAttributeGroup {
+    name?: string | undefined;
+    attributeGroups?: AttributeGroup[] | undefined;
+    attributes?: Attribute[] | undefined;
+
+    constructor(data?: IAttributeGroup) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.name = data["Name"];
+            if (data["AttributeGroups"] && data["AttributeGroups"].constructor === Array) {
+                this.attributeGroups = [];
+                for (let item of data["AttributeGroups"])
+                    this.attributeGroups.push(AttributeGroup.fromJS(item));
+            }
+            if (data["Attributes"] && data["Attributes"].constructor === Array) {
+                this.attributes = [];
+                for (let item of data["Attributes"])
+                    this.attributes.push(Attribute.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): AttributeGroup {
+        data = typeof data === 'object' ? data : {};
+        let result = new AttributeGroup();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Name"] = this.name;
+        if (this.attributeGroups && this.attributeGroups.constructor === Array) {
+            data["AttributeGroups"] = [];
+            for (let item of this.attributeGroups)
+                data["AttributeGroups"].push(item.toJSON());
+        }
+        if (this.attributes && this.attributes.constructor === Array) {
+            data["Attributes"] = [];
+            for (let item of this.attributes)
+                data["Attributes"].push(item.toJSON());
+        }
+        return data;
+    }
+}
+
+export interface IAttributeGroup {
+    name?: string | undefined;
+    attributeGroups?: AttributeGroup[] | undefined;
+    attributes?: Attribute[] | undefined;
+}
+
+export class Catalog implements ICatalog {
+    supportedOperations?: string[] | undefined;
+    schemas?: Schema[] | undefined;
+
+    constructor(data?: ICatalog) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            if (data["SupportedOperations"] && data["SupportedOperations"].constructor === Array) {
+                this.supportedOperations = [];
+                for (let item of data["SupportedOperations"])
+                    this.supportedOperations.push(item);
+            }
+            if (data["Schemas"] && data["Schemas"].constructor === Array) {
+                this.schemas = [];
+                for (let item of data["Schemas"])
+                    this.schemas.push(Schema.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): Catalog {
+        data = typeof data === 'object' ? data : {};
+        let result = new Catalog();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.supportedOperations && this.supportedOperations.constructor === Array) {
+            data["SupportedOperations"] = [];
+            for (let item of this.supportedOperations)
+                data["SupportedOperations"].push(item);
+        }
+        if (this.schemas && this.schemas.constructor === Array) {
+            data["Schemas"] = [];
+            for (let item of this.schemas)
+                data["Schemas"].push(item.toJSON());
+        }
+        return data;
+    }
+}
+
+export interface ICatalog {
+    supportedOperations?: string[] | undefined;
+    schemas?: Schema[] | undefined;
+}
+
+export class Schema implements ISchema {
+    rootAttributeGroup?: AttributeGroup | undefined;
+    displayName?: string | undefined;
+    augmentedFrom?: string | undefined;
+    rawName?: string | undefined;
+    problemDescription?: string | undefined;
+    darpaProblemDoc?: DarpaProblemDoc | undefined;
+    distinctAttributeParameters?: AttributeParameters | undefined;
+    darpaDatasetDoc?: DarpaDatasetDoc | undefined;
+    darpaDatasetLocation?: string | undefined;
+    isMultiResourceData?: boolean | undefined;
+    problemFinderRows?: ProblemFinderRows[] | undefined;
+    correlationRows?: ProblemFinderRows[] | undefined;
+
+    constructor(data?: ISchema) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.rootAttributeGroup = data["RootAttributeGroup"] ? AttributeGroup.fromJS(data["RootAttributeGroup"]) : <any>undefined;
+            this.displayName = data["DisplayName"];
+            this.augmentedFrom = data["AugmentedFrom"];
+            this.rawName = data["RawName"];
+            this.problemDescription = data["ProblemDescription"];
+            this.darpaProblemDoc = data["DarpaProblemDoc"] ? DarpaProblemDoc.fromJS(data["DarpaProblemDoc"]) : <any>undefined;
+            this.distinctAttributeParameters = data["DistinctAttributeParameters"] ? AttributeParameters.fromJS(data["DistinctAttributeParameters"]) : <any>undefined;
+            this.darpaDatasetDoc = data["DarpaDatasetDoc"] ? DarpaDatasetDoc.fromJS(data["DarpaDatasetDoc"]) : <any>undefined;
+            this.darpaDatasetLocation = data["DarpaDatasetLocation"];
+            this.isMultiResourceData = data["IsMultiResourceData"];
+            if (data["ProblemFinderRows"] && data["ProblemFinderRows"].constructor === Array) {
+                this.problemFinderRows = [];
+                for (let item of data["ProblemFinderRows"])
+                    this.problemFinderRows.push(ProblemFinderRows.fromJS(item));
+            }
+            if (data["CorrelationRows"] && data["CorrelationRows"].constructor === Array) {
+                this.correlationRows = [];
+                for (let item of data["CorrelationRows"])
+                    this.correlationRows.push(ProblemFinderRows.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): Schema {
+        data = typeof data === 'object' ? data : {};
+        let result = new Schema();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["RootAttributeGroup"] = this.rootAttributeGroup ? this.rootAttributeGroup.toJSON() : <any>undefined;
+        data["DisplayName"] = this.displayName;
+        data["AugmentedFrom"] = this.augmentedFrom;
+        data["RawName"] = this.rawName;
+        data["ProblemDescription"] = this.problemDescription;
+        data["DarpaProblemDoc"] = this.darpaProblemDoc ? this.darpaProblemDoc.toJSON() : <any>undefined;
+        data["DistinctAttributeParameters"] = this.distinctAttributeParameters ? this.distinctAttributeParameters.toJSON() : <any>undefined;
+        data["DarpaDatasetDoc"] = this.darpaDatasetDoc ? this.darpaDatasetDoc.toJSON() : <any>undefined;
+        data["DarpaDatasetLocation"] = this.darpaDatasetLocation;
+        data["IsMultiResourceData"] = this.isMultiResourceData;
+        if (this.problemFinderRows && this.problemFinderRows.constructor === Array) {
+            data["ProblemFinderRows"] = [];
+            for (let item of this.problemFinderRows)
+                data["ProblemFinderRows"].push(item.toJSON());
+        }
+        if (this.correlationRows && this.correlationRows.constructor === Array) {
+            data["CorrelationRows"] = [];
+            for (let item of this.correlationRows)
+                data["CorrelationRows"].push(item.toJSON());
+        }
+        return data;
+    }
+}
+
+export interface ISchema {
+    rootAttributeGroup?: AttributeGroup | undefined;
+    displayName?: string | undefined;
+    augmentedFrom?: string | undefined;
+    rawName?: string | undefined;
+    problemDescription?: string | undefined;
+    darpaProblemDoc?: DarpaProblemDoc | undefined;
+    distinctAttributeParameters?: AttributeParameters | undefined;
+    darpaDatasetDoc?: DarpaDatasetDoc | undefined;
+    darpaDatasetLocation?: string | undefined;
+    isMultiResourceData?: boolean | undefined;
+    problemFinderRows?: ProblemFinderRows[] | undefined;
+    correlationRows?: ProblemFinderRows[] | undefined;
+}
+
+export class DarpaProblemDoc implements IDarpaProblemDoc {
+    about?: ProblemAbout | undefined;
+    inputs?: ProblemInputs | undefined;
+
+    constructor(data?: IDarpaProblemDoc) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.about = data["about"] ? ProblemAbout.fromJS(data["about"]) : <any>undefined;
+            this.inputs = data["inputs"] ? ProblemInputs.fromJS(data["inputs"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): DarpaProblemDoc {
+        data = typeof data === 'object' ? data : {};
+        let result = new DarpaProblemDoc();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["about"] = this.about ? this.about.toJSON() : <any>undefined;
+        data["inputs"] = this.inputs ? this.inputs.toJSON() : <any>undefined;
+        return data;
+    }
+}
+
+export interface IDarpaProblemDoc {
+    about?: ProblemAbout | undefined;
+    inputs?: ProblemInputs | undefined;
+}
+
+export class ProblemAbout implements IProblemAbout {
+    problemID?: string | undefined;
+    problemName?: string | undefined;
+    problemDescription?: string | undefined;
+    taskType?: string | undefined;
+    taskSubType?: string | undefined;
+    problemSchemaVersion?: string | undefined;
+    problemVersion?: string | undefined;
+
+    constructor(data?: IProblemAbout) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.problemID = data["problemID"];
+            this.problemName = data["problemName"];
+            this.problemDescription = data["problemDescription"];
+            this.taskType = data["taskType"];
+            this.taskSubType = data["taskSubType"];
+            this.problemSchemaVersion = data["problemSchemaVersion"];
+            this.problemVersion = data["problemVersion"];
+        }
+    }
+
+    static fromJS(data: any): ProblemAbout {
+        data = typeof data === 'object' ? data : {};
+        let result = new ProblemAbout();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["problemID"] = this.problemID;
+        data["problemName"] = this.problemName;
+        data["problemDescription"] = this.problemDescription;
+        data["taskType"] = this.taskType;
+        data["taskSubType"] = this.taskSubType;
+        data["problemSchemaVersion"] = this.problemSchemaVersion;
+        data["problemVersion"] = this.problemVersion;
+        return data;
+    }
+}
+
+export interface IProblemAbout {
+    problemID?: string | undefined;
+    problemName?: string | undefined;
+    problemDescription?: string | undefined;
+    taskType?: string | undefined;
+    taskSubType?: string | undefined;
+    problemSchemaVersion?: string | undefined;
+    problemVersion?: string | undefined;
+}
+
+export class ProblemInputs implements IProblemInputs {
+    data?: ProblemData[] | undefined;
+    performanceMetrics?: ProblemPerformanceMetric[] | undefined;
+
+    constructor(data?: IProblemInputs) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            if (data["data"] && data["data"].constructor === Array) {
+                this.data = [];
+                for (let item of data["data"])
+                    this.data.push(ProblemData.fromJS(item));
+            }
+            if (data["performanceMetrics"] && data["performanceMetrics"].constructor === Array) {
+                this.performanceMetrics = [];
+                for (let item of data["performanceMetrics"])
+                    this.performanceMetrics.push(ProblemPerformanceMetric.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): ProblemInputs {
+        data = typeof data === 'object' ? data : {};
+        let result = new ProblemInputs();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.data && this.data.constructor === Array) {
+            data["data"] = [];
+            for (let item of this.data)
+                data["data"].push(item.toJSON());
+        }
+        if (this.performanceMetrics && this.performanceMetrics.constructor === Array) {
+            data["performanceMetrics"] = [];
+            for (let item of this.performanceMetrics)
+                data["performanceMetrics"].push(item.toJSON());
+        }
+        return data;
+    }
+}
+
+export interface IProblemInputs {
+    data?: ProblemData[] | undefined;
+    performanceMetrics?: ProblemPerformanceMetric[] | undefined;
+}
+
+export class ProblemData implements IProblemData {
+    datasetID?: string | undefined;
+    targets?: ProblemTarget[] | undefined;
+
+    constructor(data?: IProblemData) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.datasetID = data["datasetID"];
+            if (data["targets"] && data["targets"].constructor === Array) {
+                this.targets = [];
+                for (let item of data["targets"])
+                    this.targets.push(ProblemTarget.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): ProblemData {
+        data = typeof data === 'object' ? data : {};
+        let result = new ProblemData();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["datasetID"] = this.datasetID;
+        if (this.targets && this.targets.constructor === Array) {
+            data["targets"] = [];
+            for (let item of this.targets)
+                data["targets"].push(item.toJSON());
+        }
+        return data;
+    }
+}
+
+export interface IProblemData {
+    datasetID?: string | undefined;
+    targets?: ProblemTarget[] | undefined;
+}
+
+export class ProblemTarget implements IProblemTarget {
+    targetIndex?: number | undefined;
+    resID?: string | undefined;
+    colIndex?: number | undefined;
+    colName?: string | undefined;
+
+    constructor(data?: IProblemTarget) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.targetIndex = data["targetIndex"];
+            this.resID = data["resID"];
+            this.colIndex = data["colIndex"];
+            this.colName = data["colName"];
+        }
+    }
+
+    static fromJS(data: any): ProblemTarget {
+        data = typeof data === 'object' ? data : {};
+        let result = new ProblemTarget();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["targetIndex"] = this.targetIndex;
+        data["resID"] = this.resID;
+        data["colIndex"] = this.colIndex;
+        data["colName"] = this.colName;
+        return data;
+    }
+}
+
+export interface IProblemTarget {
+    targetIndex?: number | undefined;
+    resID?: string | undefined;
+    colIndex?: number | undefined;
+    colName?: string | undefined;
+}
+
+export class ProblemPerformanceMetric implements IProblemPerformanceMetric {
+    metric?: string | undefined;
+
+    constructor(data?: IProblemPerformanceMetric) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.metric = data["metric"];
+        }
+    }
+
+    static fromJS(data: any): ProblemPerformanceMetric {
+        data = typeof data === 'object' ? data : {};
+        let result = new ProblemPerformanceMetric();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["metric"] = this.metric;
+        return data;
+    }
+}
+
+export interface IProblemPerformanceMetric {
+    metric?: string | undefined;
+}
+
+export class DarpaDatasetDoc implements IDarpaDatasetDoc {
+    about?: DatasetAbout | undefined;
+    dataResources?: Resource[] | undefined;
+
+    constructor(data?: IDarpaDatasetDoc) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.about = data["about"] ? DatasetAbout.fromJS(data["about"]) : <any>undefined;
+            if (data["dataResources"] && data["dataResources"].constructor === Array) {
+                this.dataResources = [];
+                for (let item of data["dataResources"])
+                    this.dataResources.push(Resource.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): DarpaDatasetDoc {
+        data = typeof data === 'object' ? data : {};
+        let result = new DarpaDatasetDoc();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["about"] = this.about ? this.about.toJSON() : <any>undefined;
+        if (this.dataResources && this.dataResources.constructor === Array) {
+            data["dataResources"] = [];
+            for (let item of this.dataResources)
+                data["dataResources"].push(item.toJSON());
+        }
+        return data;
+    }
+}
+
+export interface IDarpaDatasetDoc {
+    about?: DatasetAbout | undefined;
+    dataResources?: Resource[] | undefined;
+}
+
+export class DatasetAbout implements IDatasetAbout {
+    datasetID?: string | undefined;
+    datasetName?: string | undefined;
+    description?: string | undefined;
+    citation?: string | undefined;
+    license?: string | undefined;
+    source?: string | undefined;
+    sourceURI?: string | undefined;
+    approximateSize?: string | undefined;
+    datasetSchemaVersion?: string | undefined;
+    redacted?: boolean | undefined;
+    datasetVersion?: string | undefined;
+
+    constructor(data?: IDatasetAbout) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.datasetID = data["datasetID"];
+            this.datasetName = data["datasetName"];
+            this.description = data["description"];
+            this.citation = data["citation"];
+            this.license = data["license"];
+            this.source = data["source"];
+            this.sourceURI = data["sourceURI"];
+            this.approximateSize = data["approximateSize"];
+            this.datasetSchemaVersion = data["datasetSchemaVersion"];
+            this.redacted = data["redacted"];
+            this.datasetVersion = data["datasetVersion"];
+        }
+    }
+
+    static fromJS(data: any): DatasetAbout {
+        data = typeof data === 'object' ? data : {};
+        let result = new DatasetAbout();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["datasetID"] = this.datasetID;
+        data["datasetName"] = this.datasetName;
+        data["description"] = this.description;
+        data["citation"] = this.citation;
+        data["license"] = this.license;
+        data["source"] = this.source;
+        data["sourceURI"] = this.sourceURI;
+        data["approximateSize"] = this.approximateSize;
+        data["datasetSchemaVersion"] = this.datasetSchemaVersion;
+        data["redacted"] = this.redacted;
+        data["datasetVersion"] = this.datasetVersion;
+        return data;
+    }
+}
+
+export interface IDatasetAbout {
+    datasetID?: string | undefined;
+    datasetName?: string | undefined;
+    description?: string | undefined;
+    citation?: string | undefined;
+    license?: string | undefined;
+    source?: string | undefined;
+    sourceURI?: string | undefined;
+    approximateSize?: string | undefined;
+    datasetSchemaVersion?: string | undefined;
+    redacted?: boolean | undefined;
+    datasetVersion?: string | undefined;
+}
+
+export class Resource implements IResource {
+    resID?: string | undefined;
+    resPath?: string | undefined;
+    resType?: string | undefined;
+    resFormat?: string[] | undefined;
+    columns?: Column[] | undefined;
+    isCollection?: boolean | undefined;
+
+    constructor(data?: IResource) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.resID = data["resID"];
+            this.resPath = data["resPath"];
+            this.resType = data["resType"];
+            if (data["resFormat"] && data["resFormat"].constructor === Array) {
+                this.resFormat = [];
+                for (let item of data["resFormat"])
+                    this.resFormat.push(item);
+            }
+            if (data["columns"] && data["columns"].constructor === Array) {
+                this.columns = [];
+                for (let item of data["columns"])
+                    this.columns.push(Column.fromJS(item));
+            }
+            this.isCollection = data["isCollection"];
+        }
+    }
+
+    static fromJS(data: any): Resource {
+        data = typeof data === 'object' ? data : {};
+        let result = new Resource();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["resID"] = this.resID;
+        data["resPath"] = this.resPath;
+        data["resType"] = this.resType;
+        if (this.resFormat && this.resFormat.constructor === Array) {
+            data["resFormat"] = [];
+            for (let item of this.resFormat)
+                data["resFormat"].push(item);
+        }
+        if (this.columns && this.columns.constructor === Array) {
+            data["columns"] = [];
+            for (let item of this.columns)
+                data["columns"].push(item.toJSON());
+        }
+        data["isCollection"] = this.isCollection;
+        return data;
+    }
+}
+
+export interface IResource {
+    resID?: string | undefined;
+    resPath?: string | undefined;
+    resType?: string | undefined;
+    resFormat?: string[] | undefined;
+    columns?: Column[] | undefined;
+    isCollection?: boolean | undefined;
+}
+
+export class Column implements IColumn {
+    colIndex?: number | undefined;
+    colDescription?: string | undefined;
+    colName?: string | undefined;
+    colType?: string | undefined;
+    role?: string[] | undefined;
+    refersTo?: Reference | undefined;
+
+    constructor(data?: IColumn) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.colIndex = data["colIndex"];
+            this.colDescription = data["colDescription"];
+            this.colName = data["colName"];
+            this.colType = data["colType"];
+            if (data["role"] && data["role"].constructor === Array) {
+                this.role = [];
+                for (let item of data["role"])
+                    this.role.push(item);
+            }
+            this.refersTo = data["refersTo"] ? Reference.fromJS(data["refersTo"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): Column {
+        data = typeof data === 'object' ? data : {};
+        let result = new Column();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["colIndex"] = this.colIndex;
+        data["colDescription"] = this.colDescription;
+        data["colName"] = this.colName;
+        data["colType"] = this.colType;
+        if (this.role && this.role.constructor === Array) {
+            data["role"] = [];
+            for (let item of this.role)
+                data["role"].push(item);
+        }
+        data["refersTo"] = this.refersTo ? this.refersTo.toJSON() : <any>undefined;
+        return data;
+    }
+}
+
+export interface IColumn {
+    colIndex?: number | undefined;
+    colDescription?: string | undefined;
+    colName?: string | undefined;
+    colType?: string | undefined;
+    role?: string[] | undefined;
+    refersTo?: Reference | undefined;
+}
+
+export class Reference implements IReference {
+    resID?: string | undefined;
+
+    constructor(data?: IReference) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.resID = data["resID"];
+        }
+    }
+
+    static fromJS(data: any): Reference {
+        data = typeof data === 'object' ? data : {};
+        let result = new Reference();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["resID"] = this.resID;
+        return data;
+    }
+}
+
+export interface IReference {
+    resID?: string | undefined;
+}
+
+export class ProblemFinderRows implements IProblemFinderRows {
+    label?: string | undefined;
+    type?: string | undefined;
+    features?: Feature[] | undefined;
+
+    constructor(data?: IProblemFinderRows) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.label = data["label"];
+            this.type = data["type"];
+            if (data["features"] && data["features"].constructor === Array) {
+                this.features = [];
+                for (let item of data["features"])
+                    this.features.push(Feature.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): ProblemFinderRows {
+        data = typeof data === 'object' ? data : {};
+        let result = new ProblemFinderRows();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["label"] = this.label;
+        data["type"] = this.type;
+        if (this.features && this.features.constructor === Array) {
+            data["features"] = [];
+            for (let item of this.features)
+                data["features"].push(item.toJSON());
+        }
+        return data;
+    }
+}
+
+export interface IProblemFinderRows {
+    label?: string | undefined;
+    type?: string | undefined;
+    features?: Feature[] | undefined;
+}
+
+export class Feature implements IFeature {
+    name?: string | undefined;
+    selected?: boolean | undefined;
+    value?: number | undefined;
+
+    constructor(data?: IFeature) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.name = data["name"];
+            this.selected = data["selected"];
+            this.value = data["value"];
+        }
+    }
+
+    static fromJS(data: any): Feature {
+        data = typeof data === 'object' ? data : {};
+        let result = new Feature();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["name"] = this.name;
+        data["selected"] = this.selected;
+        data["value"] = this.value;
+        return data;
+    }
+}
+
+export interface IFeature {
+    name?: string | undefined;
+    selected?: boolean | undefined;
+    value?: number | undefined;
+}
+
+export enum DataType2 {
+    Int = 0,
+    String = 1,
+    Float = 2,
+    Double = 3,
+    DateTime = 4,
+    Object = 5,
+    Undefined = 6,
+}
+
+export abstract class DataTypeExtensions implements IDataTypeExtensions {
+
+    constructor(data?: IDataTypeExtensions) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): DataTypeExtensions {
+        data = typeof data === 'object' ? data : {};
+        throw new Error("The abstract class 'DataTypeExtensions' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        return data;
+    }
+}
+
+export interface IDataTypeExtensions {
+}
+
+export class ResObject implements IResObject {
+    columnName?: string | undefined;
+
+    constructor(data?: IResObject) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.columnName = data["columnName"];
+        }
+    }
+
+    static fromJS(data: any): ResObject {
+        data = typeof data === 'object' ? data : {};
+        let result = new ResObject();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["columnName"] = this.columnName;
+        return data;
+    }
+}
+
+export interface IResObject {
+    columnName?: string | undefined;
+}
+
+export class Exception implements IException {
+    message?: string | undefined;
+    innerException?: Exception | undefined;
+    stackTrace?: string | undefined;
+    source?: string | undefined;
+
+    constructor(data?: IException) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.message = data["Message"];
+            this.innerException = data["InnerException"] ? Exception.fromJS(data["InnerException"]) : <any>undefined;
+            this.stackTrace = data["StackTrace"];
+            this.source = data["Source"];
+        }
+    }
+
+    static fromJS(data: any): Exception {
+        data = typeof data === 'object' ? data : {};
+        let result = new Exception();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Message"] = this.message;
+        data["InnerException"] = this.innerException ? this.innerException.toJSON() : <any>undefined;
+        data["StackTrace"] = this.stackTrace;
+        data["Source"] = this.source;
+        return data;
+    }
+}
+
+export interface IException {
+    message?: string | undefined;
+    innerException?: Exception | undefined;
+    stackTrace?: string | undefined;
+    source?: string | undefined;
+}
+
+export class IDEAException extends Exception implements IIDEAException {
+
+    constructor(data?: IIDEAException) {
+        super(data);
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): IDEAException {
+        data = typeof data === 'object' ? data : {};
+        let result = new IDEAException();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IIDEAException extends IException {
+}
+
+export class CodeParameters implements ICodeParameters {
+    attributeCodeParameters?: AttributeCodeParameters[] | undefined;
+    adapterName?: string | undefined;
+
+    constructor(data?: ICodeParameters) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            if (data["AttributeCodeParameters"] && data["AttributeCodeParameters"].constructor === Array) {
+                this.attributeCodeParameters = [];
+                for (let item of data["AttributeCodeParameters"])
+                    this.attributeCodeParameters.push(AttributeCodeParameters.fromJS(item));
+            }
+            this.adapterName = data["AdapterName"];
+        }
+    }
+
+    static fromJS(data: any): CodeParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new CodeParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.attributeCodeParameters && this.attributeCodeParameters.constructor === Array) {
+            data["AttributeCodeParameters"] = [];
+            for (let item of this.attributeCodeParameters)
+                data["AttributeCodeParameters"].push(item.toJSON());
+        }
+        data["AdapterName"] = this.adapterName;
+        return data;
+    }
+}
+
+export interface ICodeParameters {
+    attributeCodeParameters?: AttributeCodeParameters[] | undefined;
+    adapterName?: string | undefined;
+}
+
+export class CompileResult implements ICompileResult {
+    compileSuccess?: boolean | undefined;
+    compileMessage?: string | undefined;
+    dataType?: DataType | undefined;
+    replaceAttributeParameters?: AttributeParameters[] | undefined;
+
+    constructor(data?: ICompileResult) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.compileSuccess = data["CompileSuccess"];
+            this.compileMessage = data["CompileMessage"];
+            this.dataType = data["DataType"];
+            if (data["ReplaceAttributeParameters"] && data["ReplaceAttributeParameters"].constructor === Array) {
+                this.replaceAttributeParameters = [];
+                for (let item of data["ReplaceAttributeParameters"])
+                    this.replaceAttributeParameters.push(AttributeParameters.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): CompileResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new CompileResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["CompileSuccess"] = this.compileSuccess;
+        data["CompileMessage"] = this.compileMessage;
+        data["DataType"] = this.dataType;
+        if (this.replaceAttributeParameters && this.replaceAttributeParameters.constructor === Array) {
+            data["ReplaceAttributeParameters"] = [];
+            for (let item of this.replaceAttributeParameters)
+                data["ReplaceAttributeParameters"].push(item.toJSON());
+        }
+        return data;
+    }
+}
+
+export interface ICompileResult {
+    compileSuccess?: boolean | undefined;
+    compileMessage?: string | undefined;
+    dataType?: DataType | undefined;
+    replaceAttributeParameters?: AttributeParameters[] | undefined;
+}
+
+export class CompileResults implements ICompileResults {
+    rawNameToCompileResult?: { [key: string]: CompileResult; } | undefined;
+
+    constructor(data?: ICompileResults) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            if (data["RawNameToCompileResult"]) {
+                this.rawNameToCompileResult = {};
+                for (let key in data["RawNameToCompileResult"]) {
+                    if (data["RawNameToCompileResult"].hasOwnProperty(key))
+                        this.rawNameToCompileResult[key] = data["RawNameToCompileResult"][key] ? CompileResult.fromJS(data["RawNameToCompileResult"][key]) : new CompileResult();
+                }
+            }
+        }
+    }
+
+    static fromJS(data: any): CompileResults {
+        data = typeof data === 'object' ? data : {};
+        let result = new CompileResults();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.rawNameToCompileResult) {
+            data["RawNameToCompileResult"] = {};
+            for (let key in this.rawNameToCompileResult) {
+                if (this.rawNameToCompileResult.hasOwnProperty(key))
+                    data["RawNameToCompileResult"][key] = this.rawNameToCompileResult[key];
+            }
+        }
+        return data;
+    }
+}
+
+export interface ICompileResults {
+    rawNameToCompileResult?: { [key: string]: CompileResult; } | undefined;
+}
+
+export abstract class UniqueJson implements IUniqueJson {
+
+    constructor(data?: IUniqueJson) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): UniqueJson {
+        data = typeof data === 'object' ? data : {};
+        throw new Error("The abstract class 'UniqueJson' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        return data;
+    }
+}
+
+export interface IUniqueJson {
+}
+
+export abstract class OperationParameters extends UniqueJson implements IOperationParameters {
+    isCachable?: boolean | undefined;
+
+    protected _discriminator: string;
+
+    constructor(data?: IOperationParameters) {
+        super(data);
+        this._discriminator = "OperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.isCachable = data["IsCachable"];
+        }
+    }
+
+    static fromJS(data: any): OperationParameters {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "DataOperationParameters") {
+            throw new Error("The abstract class 'DataOperationParameters' cannot be instantiated.");
+        }
+        if (data["discriminator"] === "ExampleOperationParameters") {
+            let result = new ExampleOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "HistogramOperationParameters") {
+            let result = new HistogramOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "DistOperationParameters") {
+            throw new Error("The abstract class 'DistOperationParameters' cannot be instantiated.");
+        }
+        if (data["discriminator"] === "OptimizerOperationParameters") {
+            let result = new OptimizerOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "RawDataOperationParameters") {
+            let result = new RawDataOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "RecommenderOperationParameters") {
+            let result = new RecommenderOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "CDFOperationParameters") {
+            let result = new CDFOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "TestDistOperationParameters") {
+            throw new Error("The abstract class 'TestDistOperationParameters' cannot be instantiated.");
+        }
+        if (data["discriminator"] === "ChiSquaredTestOperationParameters") {
+            let result = new ChiSquaredTestOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "HypothesisTestParameters") {
+            throw new Error("The abstract class 'HypothesisTestParameters' cannot be instantiated.");
+        }
+        if (data["discriminator"] === "CorrelationTestOperationParameters") {
+            let result = new CorrelationTestOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "EmpiricalDistOperationParameters") {
+            let result = new EmpiricalDistOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "KSTestOperationParameters") {
+            let result = new KSTestOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "NewModelOperationParameters") {
+            let result = new NewModelOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "ModelOperationParameters") {
+            throw new Error("The abstract class 'ModelOperationParameters' cannot be instantiated.");
+        }
+        if (data["discriminator"] === "RootMeanSquareTestOperationParameters") {
+            let result = new RootMeanSquareTestOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "TTestOperationParameters") {
+            let result = new TTestOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "FeatureImportanceOperationParameters") {
+            let result = new FeatureImportanceOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "SampleOperationParameters") {
+            let result = new SampleOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "AddComparisonParameters") {
+            let result = new AddComparisonParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "GetModelStateParameters") {
+            let result = new GetModelStateParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "FrequentItemsetOperationParameters") {
+            let result = new FrequentItemsetOperationParameters();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'OperationParameters' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        data["IsCachable"] = this.isCachable;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IOperationParameters extends IUniqueJson {
+    isCachable?: boolean | undefined;
+}
+
+export abstract class DataOperationParameters extends OperationParameters implements IDataOperationParameters {
+    sampleStreamBlockSize?: number | undefined;
+    adapterName?: string | undefined;
+    isCachable?: boolean | undefined;
+
+    constructor(data?: IDataOperationParameters) {
+        super(data);
+        this._discriminator = "DataOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.sampleStreamBlockSize = data["SampleStreamBlockSize"];
+            this.adapterName = data["AdapterName"];
+            this.isCachable = data["IsCachable"];
+        }
+    }
+
+    static fromJS(data: any): DataOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "ExampleOperationParameters") {
+            let result = new ExampleOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "HistogramOperationParameters") {
+            let result = new HistogramOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "DistOperationParameters") {
+            throw new Error("The abstract class 'DistOperationParameters' cannot be instantiated.");
+        }
+        if (data["discriminator"] === "OptimizerOperationParameters") {
+            let result = new OptimizerOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "RawDataOperationParameters") {
+            let result = new RawDataOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "RecommenderOperationParameters") {
+            let result = new RecommenderOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "CDFOperationParameters") {
+            let result = new CDFOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "TestDistOperationParameters") {
+            throw new Error("The abstract class 'TestDistOperationParameters' cannot be instantiated.");
+        }
+        if (data["discriminator"] === "EmpiricalDistOperationParameters") {
+            let result = new EmpiricalDistOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "FeatureImportanceOperationParameters") {
+            let result = new FeatureImportanceOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "SampleOperationParameters") {
+            let result = new SampleOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "FrequentItemsetOperationParameters") {
+            let result = new FrequentItemsetOperationParameters();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'DataOperationParameters' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["SampleStreamBlockSize"] = this.sampleStreamBlockSize;
+        data["AdapterName"] = this.adapterName;
+        data["IsCachable"] = this.isCachable;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IDataOperationParameters extends IOperationParameters {
+    sampleStreamBlockSize?: number | undefined;
+    adapterName?: string | undefined;
+    isCachable?: boolean | undefined;
+}
+
+export class ExampleOperationParameters extends DataOperationParameters implements IExampleOperationParameters {
+    filter?: string | undefined;
+    attributeParameters?: AttributeParameters[] | undefined;
+    attributeCodeParameters?: AttributeCaclculatedParameters[] | undefined;
+    dummyValue?: number | undefined;
+    exampleType?: string | undefined;
+
+    constructor(data?: IExampleOperationParameters) {
+        super(data);
+        this._discriminator = "ExampleOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.filter = data["Filter"];
+            if (data["AttributeParameters"] && data["AttributeParameters"].constructor === Array) {
+                this.attributeParameters = [];
+                for (let item of data["AttributeParameters"])
+                    this.attributeParameters.push(AttributeParameters.fromJS(item));
+            }
+            if (data["AttributeCodeParameters"] && data["AttributeCodeParameters"].constructor === Array) {
+                this.attributeCodeParameters = [];
+                for (let item of data["AttributeCodeParameters"])
+                    this.attributeCodeParameters.push(AttributeCaclculatedParameters.fromJS(item));
+            }
+            this.dummyValue = data["DummyValue"];
+            this.exampleType = data["ExampleType"];
+        }
+    }
+
+    static fromJS(data: any): ExampleOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new ExampleOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Filter"] = this.filter;
+        if (this.attributeParameters && this.attributeParameters.constructor === Array) {
+            data["AttributeParameters"] = [];
+            for (let item of this.attributeParameters)
+                data["AttributeParameters"].push(item.toJSON());
+        }
+        if (this.attributeCodeParameters && this.attributeCodeParameters.constructor === Array) {
+            data["AttributeCodeParameters"] = [];
+            for (let item of this.attributeCodeParameters)
+                data["AttributeCodeParameters"].push(item.toJSON());
+        }
+        data["DummyValue"] = this.dummyValue;
+        data["ExampleType"] = this.exampleType;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IExampleOperationParameters extends IDataOperationParameters {
+    filter?: string | undefined;
+    attributeParameters?: AttributeParameters[] | undefined;
+    attributeCodeParameters?: AttributeCaclculatedParameters[] | undefined;
+    dummyValue?: number | undefined;
+    exampleType?: string | undefined;
+}
+
+export abstract class DistOperationParameters extends DataOperationParameters implements IDistOperationParameters {
+    filter?: string | undefined;
+    attributeCalculatedParameters?: AttributeCaclculatedParameters[] | undefined;
+
+    constructor(data?: IDistOperationParameters) {
+        super(data);
+        this._discriminator = "DistOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.filter = data["Filter"];
+            if (data["AttributeCalculatedParameters"] && data["AttributeCalculatedParameters"].constructor === Array) {
+                this.attributeCalculatedParameters = [];
+                for (let item of data["AttributeCalculatedParameters"])
+                    this.attributeCalculatedParameters.push(AttributeCaclculatedParameters.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): DistOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "HistogramOperationParameters") {
+            let result = new HistogramOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "OptimizerOperationParameters") {
+            let result = new OptimizerOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "RawDataOperationParameters") {
+            let result = new RawDataOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "CDFOperationParameters") {
+            let result = new CDFOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "TestDistOperationParameters") {
+            throw new Error("The abstract class 'TestDistOperationParameters' cannot be instantiated.");
+        }
+        if (data["discriminator"] === "EmpiricalDistOperationParameters") {
+            let result = new EmpiricalDistOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "FeatureImportanceOperationParameters") {
+            let result = new FeatureImportanceOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "SampleOperationParameters") {
+            let result = new SampleOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "FrequentItemsetOperationParameters") {
+            let result = new FrequentItemsetOperationParameters();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'DistOperationParameters' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Filter"] = this.filter;
+        if (this.attributeCalculatedParameters && this.attributeCalculatedParameters.constructor === Array) {
+            data["AttributeCalculatedParameters"] = [];
+            for (let item of this.attributeCalculatedParameters)
+                data["AttributeCalculatedParameters"].push(item.toJSON());
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IDistOperationParameters extends IDataOperationParameters {
+    filter?: string | undefined;
+    attributeCalculatedParameters?: AttributeCaclculatedParameters[] | undefined;
+}
+
+export class HistogramOperationParameters extends DistOperationParameters implements IHistogramOperationParameters {
+    sortPerBinAggregateParameter?: AggregateParameters | undefined;
+    binningParameters?: BinningParameters[] | undefined;
+    perBinAggregateParameters?: AggregateParameters[] | undefined;
+    globalAggregateParameters?: AggregateParameters[] | undefined;
+    brushes?: string[] | undefined;
+    enableBrushComputation?: boolean | undefined;
+    degreeOfParallism?: number | undefined;
+
+    constructor(data?: IHistogramOperationParameters) {
+        super(data);
+        this._discriminator = "HistogramOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.sortPerBinAggregateParameter = data["SortPerBinAggregateParameter"] ? AggregateParameters.fromJS(data["SortPerBinAggregateParameter"]) : <any>undefined;
+            if (data["BinningParameters"] && data["BinningParameters"].constructor === Array) {
+                this.binningParameters = [];
+                for (let item of data["BinningParameters"])
+                    this.binningParameters.push(BinningParameters.fromJS(item));
+            }
+            if (data["PerBinAggregateParameters"] && data["PerBinAggregateParameters"].constructor === Array) {
+                this.perBinAggregateParameters = [];
+                for (let item of data["PerBinAggregateParameters"])
+                    this.perBinAggregateParameters.push(AggregateParameters.fromJS(item));
+            }
+            if (data["GlobalAggregateParameters"] && data["GlobalAggregateParameters"].constructor === Array) {
+                this.globalAggregateParameters = [];
+                for (let item of data["GlobalAggregateParameters"])
+                    this.globalAggregateParameters.push(AggregateParameters.fromJS(item));
+            }
+            if (data["Brushes"] && data["Brushes"].constructor === Array) {
+                this.brushes = [];
+                for (let item of data["Brushes"])
+                    this.brushes.push(item);
+            }
+            this.enableBrushComputation = data["EnableBrushComputation"];
+            this.degreeOfParallism = data["DegreeOfParallism"];
+        }
+    }
+
+    static fromJS(data: any): HistogramOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new HistogramOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["SortPerBinAggregateParameter"] = this.sortPerBinAggregateParameter ? this.sortPerBinAggregateParameter.toJSON() : <any>undefined;
+        if (this.binningParameters && this.binningParameters.constructor === Array) {
+            data["BinningParameters"] = [];
+            for (let item of this.binningParameters)
+                data["BinningParameters"].push(item.toJSON());
+        }
+        if (this.perBinAggregateParameters && this.perBinAggregateParameters.constructor === Array) {
+            data["PerBinAggregateParameters"] = [];
+            for (let item of this.perBinAggregateParameters)
+                data["PerBinAggregateParameters"].push(item.toJSON());
+        }
+        if (this.globalAggregateParameters && this.globalAggregateParameters.constructor === Array) {
+            data["GlobalAggregateParameters"] = [];
+            for (let item of this.globalAggregateParameters)
+                data["GlobalAggregateParameters"].push(item.toJSON());
+        }
+        if (this.brushes && this.brushes.constructor === Array) {
+            data["Brushes"] = [];
+            for (let item of this.brushes)
+                data["Brushes"].push(item);
+        }
+        data["EnableBrushComputation"] = this.enableBrushComputation;
+        data["DegreeOfParallism"] = this.degreeOfParallism;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IHistogramOperationParameters extends IDistOperationParameters {
+    sortPerBinAggregateParameter?: AggregateParameters | undefined;
+    binningParameters?: BinningParameters[] | undefined;
+    perBinAggregateParameters?: AggregateParameters[] | undefined;
+    globalAggregateParameters?: AggregateParameters[] | undefined;
+    brushes?: string[] | undefined;
+    enableBrushComputation?: boolean | undefined;
+    degreeOfParallism?: number | undefined;
+}
+
+export class OptimizerOperationParameters extends DistOperationParameters implements IOptimizerOperationParameters {
+    taskType?: TaskType | undefined;
+    taskSubType?: TaskSubType | undefined;
+    metricType?: MetricType | undefined;
+    labelAttribute?: AttributeParameters | undefined;
+    featureAttributes?: AttributeParameters[] | undefined;
+    requiredPrimitives?: string[] | undefined;
+    pythonFilter?: string | undefined;
+    trainFilter?: string | undefined;
+    pythonTrainFilter?: string | undefined;
+    testFilter?: string | undefined;
+    pythonTestFilter?: string | undefined;
+
+    constructor(data?: IOptimizerOperationParameters) {
+        super(data);
+        this._discriminator = "OptimizerOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.taskType = data["TaskType"];
+            this.taskSubType = data["TaskSubType"];
+            this.metricType = data["MetricType"];
+            this.labelAttribute = data["LabelAttribute"] ? AttributeParameters.fromJS(data["LabelAttribute"]) : <any>undefined;
+            if (data["FeatureAttributes"] && data["FeatureAttributes"].constructor === Array) {
+                this.featureAttributes = [];
+                for (let item of data["FeatureAttributes"])
+                    this.featureAttributes.push(AttributeParameters.fromJS(item));
+            }
+            if (data["RequiredPrimitives"] && data["RequiredPrimitives"].constructor === Array) {
+                this.requiredPrimitives = [];
+                for (let item of data["RequiredPrimitives"])
+                    this.requiredPrimitives.push(item);
+            }
+            this.pythonFilter = data["PythonFilter"];
+            this.trainFilter = data["TrainFilter"];
+            this.pythonTrainFilter = data["PythonTrainFilter"];
+            this.testFilter = data["TestFilter"];
+            this.pythonTestFilter = data["PythonTestFilter"];
+        }
+    }
+
+    static fromJS(data: any): OptimizerOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new OptimizerOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["TaskType"] = this.taskType;
+        data["TaskSubType"] = this.taskSubType;
+        data["MetricType"] = this.metricType;
+        data["LabelAttribute"] = this.labelAttribute ? this.labelAttribute.toJSON() : <any>undefined;
+        if (this.featureAttributes && this.featureAttributes.constructor === Array) {
+            data["FeatureAttributes"] = [];
+            for (let item of this.featureAttributes)
+                data["FeatureAttributes"].push(item.toJSON());
+        }
+        if (this.requiredPrimitives && this.requiredPrimitives.constructor === Array) {
+            data["RequiredPrimitives"] = [];
+            for (let item of this.requiredPrimitives)
+                data["RequiredPrimitives"].push(item);
+        }
+        data["PythonFilter"] = this.pythonFilter;
+        data["TrainFilter"] = this.trainFilter;
+        data["PythonTrainFilter"] = this.pythonTrainFilter;
+        data["TestFilter"] = this.testFilter;
+        data["PythonTestFilter"] = this.pythonTestFilter;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IOptimizerOperationParameters extends IDistOperationParameters {
+    taskType?: TaskType | undefined;
+    taskSubType?: TaskSubType | undefined;
+    metricType?: MetricType | undefined;
+    labelAttribute?: AttributeParameters | undefined;
+    featureAttributes?: AttributeParameters[] | undefined;
+    requiredPrimitives?: string[] | undefined;
+    pythonFilter?: string | undefined;
+    trainFilter?: string | undefined;
+    pythonTrainFilter?: string | undefined;
+    testFilter?: string | undefined;
+    pythonTestFilter?: string | undefined;
+}
+
+export enum TaskType {
+    Undefined = 0,
+    Classification = 1,
+    Regression = 2,
+    Clustering = 3,
+    LinkPrediction = 4,
+    VertexNomination = 5,
+    CommunityDetection = 6,
+    GraphClustering = 7,
+    GraphMatching = 8,
+    TimeSeriesForecasting = 9,
+    CollaborativeFiltering = 10,
+}
+
+export enum TaskSubType {
+    Undefined = 0,
+    None = 1,
+    Binary = 2,
+    Multiclass = 3,
+    Multilabel = 4,
+    Univariate = 5,
+    Multivariate = 6,
+    Overlapping = 7,
+    Nonoverlapping = 8,
+}
+
+export enum MetricType {
+    MetricUndefined = 0,
+    Accuracy = 1,
+    Precision = 2,
+    Recall = 3,
+    F1 = 4,
+    F1Micro = 5,
+    F1Macro = 6,
+    RocAuc = 7,
+    RocAucMicro = 8,
+    RocAucMacro = 9,
+    MeanSquaredError = 10,
+    RootMeanSquaredError = 11,
+    RootMeanSquaredErrorAvg = 12,
+    MeanAbsoluteError = 13,
+    RSquared = 14,
+    NormalizedMutualInformation = 15,
+    JaccardSimilarityScore = 16,
+    PrecisionAtTopK = 17,
+    ObjectDetectionAveragePrecision = 18,
+    Loss = 100,
+}
+
+export class RawDataOperationParameters extends DistOperationParameters implements IRawDataOperationParameters {
+    sortUpRawName?: string | undefined;
+    sortDownRawName?: string | undefined;
+    numRecords?: number | undefined;
+    binningParameters?: BinningParameters[] | undefined;
+    brushes?: string[] | undefined;
+    enableBrushComputation?: boolean | undefined;
+
+    constructor(data?: IRawDataOperationParameters) {
+        super(data);
+        this._discriminator = "RawDataOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.sortUpRawName = data["SortUpRawName"];
+            this.sortDownRawName = data["SortDownRawName"];
+            this.numRecords = data["NumRecords"];
+            if (data["BinningParameters"] && data["BinningParameters"].constructor === Array) {
+                this.binningParameters = [];
+                for (let item of data["BinningParameters"])
+                    this.binningParameters.push(BinningParameters.fromJS(item));
+            }
+            if (data["Brushes"] && data["Brushes"].constructor === Array) {
+                this.brushes = [];
+                for (let item of data["Brushes"])
+                    this.brushes.push(item);
+            }
+            this.enableBrushComputation = data["EnableBrushComputation"];
+        }
+    }
+
+    static fromJS(data: any): RawDataOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new RawDataOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["SortUpRawName"] = this.sortUpRawName;
+        data["SortDownRawName"] = this.sortDownRawName;
+        data["NumRecords"] = this.numRecords;
+        if (this.binningParameters && this.binningParameters.constructor === Array) {
+            data["BinningParameters"] = [];
+            for (let item of this.binningParameters)
+                data["BinningParameters"].push(item.toJSON());
+        }
+        if (this.brushes && this.brushes.constructor === Array) {
+            data["Brushes"] = [];
+            for (let item of this.brushes)
+                data["Brushes"].push(item);
+        }
+        data["EnableBrushComputation"] = this.enableBrushComputation;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IRawDataOperationParameters extends IDistOperationParameters {
+    sortUpRawName?: string | undefined;
+    sortDownRawName?: string | undefined;
+    numRecords?: number | undefined;
+    binningParameters?: BinningParameters[] | undefined;
+    brushes?: string[] | undefined;
+    enableBrushComputation?: boolean | undefined;
+}
+
+export class RecommenderOperationParameters extends DataOperationParameters implements IRecommenderOperationParameters {
+    target?: HistogramOperationParameters | undefined;
+    budget?: number | undefined;
+    modelId?: ModelId | undefined;
+    includeAttributeParameters?: AttributeParameters[] | undefined;
+    excludeAttributeParameters?: AttributeParameters[] | undefined;
+    riskControlType?: RiskControlType | undefined;
+
+    constructor(data?: IRecommenderOperationParameters) {
+        super(data);
+        this._discriminator = "RecommenderOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.target = data["Target"] ? HistogramOperationParameters.fromJS(data["Target"]) : <any>undefined;
+            this.budget = data["Budget"];
+            this.modelId = data["ModelId"] ? ModelId.fromJS(data["ModelId"]) : <any>undefined;
+            if (data["IncludeAttributeParameters"] && data["IncludeAttributeParameters"].constructor === Array) {
+                this.includeAttributeParameters = [];
+                for (let item of data["IncludeAttributeParameters"])
+                    this.includeAttributeParameters.push(AttributeParameters.fromJS(item));
+            }
+            if (data["ExcludeAttributeParameters"] && data["ExcludeAttributeParameters"].constructor === Array) {
+                this.excludeAttributeParameters = [];
+                for (let item of data["ExcludeAttributeParameters"])
+                    this.excludeAttributeParameters.push(AttributeParameters.fromJS(item));
+            }
+            this.riskControlType = data["RiskControlType"];
+        }
+    }
+
+    static fromJS(data: any): RecommenderOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new RecommenderOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Target"] = this.target ? this.target.toJSON() : <any>undefined;
+        data["Budget"] = this.budget;
+        data["ModelId"] = this.modelId ? this.modelId.toJSON() : <any>undefined;
+        if (this.includeAttributeParameters && this.includeAttributeParameters.constructor === Array) {
+            data["IncludeAttributeParameters"] = [];
+            for (let item of this.includeAttributeParameters)
+                data["IncludeAttributeParameters"].push(item.toJSON());
+        }
+        if (this.excludeAttributeParameters && this.excludeAttributeParameters.constructor === Array) {
+            data["ExcludeAttributeParameters"] = [];
+            for (let item of this.excludeAttributeParameters)
+                data["ExcludeAttributeParameters"].push(item.toJSON());
+        }
+        data["RiskControlType"] = this.riskControlType;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IRecommenderOperationParameters extends IDataOperationParameters {
+    target?: HistogramOperationParameters | undefined;
+    budget?: number | undefined;
+    modelId?: ModelId | undefined;
+    includeAttributeParameters?: AttributeParameters[] | undefined;
+    excludeAttributeParameters?: AttributeParameters[] | undefined;
+    riskControlType?: RiskControlType | undefined;
+}
+
+export class ModelId implements IModelId {
+    value?: string | undefined;
+
+    constructor(data?: IModelId) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): ModelId {
+        data = typeof data === 'object' ? data : {};
+        let result = new ModelId();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        return data;
+    }
+}
+
+export interface IModelId {
+    value?: string | undefined;
+}
+
+export enum RiskControlType {
+    PCER = 0,
+    Bonferroni = 1,
+    AdaBonferroni = 2,
+    HolmBonferroni = 3,
+    BHFDR = 4,
+    SeqFDR = 5,
+    AlphaFDR = 6,
+    BestFootForward = 7,
+    BetaFarsighted = 8,
+    BetaFarsightedWithSupport = 9,
+    GammaFixed = 10,
+    DeltaHopeful = 11,
+    EpsilonHybrid = 12,
+    EpsilonHybridWithoutSupport = 13,
+    PsiSupport = 14,
+    ZetaDynamic = 15,
+    Unknown = 16,
+}
+
+export abstract class TestDistOperationParameters extends DistOperationParameters implements ITestDistOperationParameters {
+    attributeParameters?: AttributeParameters[] | undefined;
+
+    constructor(data?: ITestDistOperationParameters) {
+        super(data);
+        this._discriminator = "TestDistOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["AttributeParameters"] && data["AttributeParameters"].constructor === Array) {
+                this.attributeParameters = [];
+                for (let item of data["AttributeParameters"])
+                    this.attributeParameters.push(AttributeParameters.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): TestDistOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "CDFOperationParameters") {
+            let result = new CDFOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "EmpiricalDistOperationParameters") {
+            let result = new EmpiricalDistOperationParameters();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'TestDistOperationParameters' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.attributeParameters && this.attributeParameters.constructor === Array) {
+            data["AttributeParameters"] = [];
+            for (let item of this.attributeParameters)
+                data["AttributeParameters"].push(item.toJSON());
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ITestDistOperationParameters extends IDistOperationParameters {
+    attributeParameters?: AttributeParameters[] | undefined;
+}
+
+export class CDFOperationParameters extends TestDistOperationParameters implements ICDFOperationParameters {
+
+    constructor(data?: ICDFOperationParameters) {
+        super(data);
+        this._discriminator = "CDFOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): CDFOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new CDFOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ICDFOperationParameters extends ITestDistOperationParameters {
+}
+
+export abstract class HypothesisTestParameters extends OperationParameters implements IHypothesisTestParameters {
+    childOperationParameters?: OperationParameters[] | undefined;
+    isCachable?: boolean | undefined;
+
+    constructor(data?: IHypothesisTestParameters) {
+        super(data);
+        this._discriminator = "HypothesisTestParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["ChildOperationParameters"] && data["ChildOperationParameters"].constructor === Array) {
+                this.childOperationParameters = [];
+                for (let item of data["ChildOperationParameters"])
+                    this.childOperationParameters.push(OperationParameters.fromJS(item));
+            }
+            this.isCachable = data["IsCachable"];
+        }
+    }
+
+    static fromJS(data: any): HypothesisTestParameters {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "ChiSquaredTestOperationParameters") {
+            let result = new ChiSquaredTestOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "CorrelationTestOperationParameters") {
+            let result = new CorrelationTestOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "KSTestOperationParameters") {
+            let result = new KSTestOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "RootMeanSquareTestOperationParameters") {
+            let result = new RootMeanSquareTestOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "TTestOperationParameters") {
+            let result = new TTestOperationParameters();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'HypothesisTestParameters' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.childOperationParameters && this.childOperationParameters.constructor === Array) {
+            data["ChildOperationParameters"] = [];
+            for (let item of this.childOperationParameters)
+                data["ChildOperationParameters"].push(item.toJSON());
+        }
+        data["IsCachable"] = this.isCachable;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IHypothesisTestParameters extends IOperationParameters {
+    childOperationParameters?: OperationParameters[] | undefined;
+    isCachable?: boolean | undefined;
+}
+
+export class ChiSquaredTestOperationParameters extends HypothesisTestParameters implements IChiSquaredTestOperationParameters {
+
+    constructor(data?: IChiSquaredTestOperationParameters) {
+        super(data);
+        this._discriminator = "ChiSquaredTestOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): ChiSquaredTestOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new ChiSquaredTestOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IChiSquaredTestOperationParameters extends IHypothesisTestParameters {
+}
+
+export class CorrelationTestOperationParameters extends HypothesisTestParameters implements ICorrelationTestOperationParameters {
+
+    constructor(data?: ICorrelationTestOperationParameters) {
+        super(data);
+        this._discriminator = "CorrelationTestOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): CorrelationTestOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new CorrelationTestOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ICorrelationTestOperationParameters extends IHypothesisTestParameters {
+}
+
+export class SubmitProblemParameters implements ISubmitProblemParameters {
+    id?: string | undefined;
+
+    constructor(data?: ISubmitProblemParameters) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.id = data["Id"];
+        }
+    }
+
+    static fromJS(data: any): SubmitProblemParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new SubmitProblemParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Id"] = this.id;
+        return data;
+    }
+}
+
+export interface ISubmitProblemParameters {
+    id?: string | undefined;
+}
+
+export class SpecifyProblemParameters implements ISpecifyProblemParameters {
+    id?: string | undefined;
+    userComment?: string | undefined;
+    optimizerOperationParameters?: OptimizerOperationParameters | undefined;
+
+    constructor(data?: ISpecifyProblemParameters) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.id = data["Id"];
+            this.userComment = data["UserComment"];
+            this.optimizerOperationParameters = data["OptimizerOperationParameters"] ? OptimizerOperationParameters.fromJS(data["OptimizerOperationParameters"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): SpecifyProblemParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new SpecifyProblemParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Id"] = this.id;
+        data["UserComment"] = this.userComment;
+        data["OptimizerOperationParameters"] = this.optimizerOperationParameters ? this.optimizerOperationParameters.toJSON() : <any>undefined;
+        return data;
+    }
+}
+
+export interface ISpecifyProblemParameters {
+    id?: string | undefined;
+    userComment?: string | undefined;
+    optimizerOperationParameters?: OptimizerOperationParameters | undefined;
+}
+
+export class EmpiricalDistOperationParameters extends TestDistOperationParameters implements IEmpiricalDistOperationParameters {
+    keepSamples?: boolean | undefined;
+
+    constructor(data?: IEmpiricalDistOperationParameters) {
+        super(data);
+        this._discriminator = "EmpiricalDistOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.keepSamples = data["KeepSamples"];
+        }
+    }
+
+    static fromJS(data: any): EmpiricalDistOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new EmpiricalDistOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["KeepSamples"] = this.keepSamples;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IEmpiricalDistOperationParameters extends ITestDistOperationParameters {
+    keepSamples?: boolean | undefined;
+}
+
+export class KSTestOperationParameters extends HypothesisTestParameters implements IKSTestOperationParameters {
+
+    constructor(data?: IKSTestOperationParameters) {
+        super(data);
+        this._discriminator = "KSTestOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): KSTestOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new KSTestOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IKSTestOperationParameters extends IHypothesisTestParameters {
+}
+
+export abstract class ModelOperationParameters extends OperationParameters implements IModelOperationParameters {
+
+    constructor(data?: IModelOperationParameters) {
+        super(data);
+        this._discriminator = "ModelOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): ModelOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "NewModelOperationParameters") {
+            let result = new NewModelOperationParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "AddComparisonParameters") {
+            let result = new AddComparisonParameters();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "GetModelStateParameters") {
+            let result = new GetModelStateParameters();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'ModelOperationParameters' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IModelOperationParameters extends IOperationParameters {
+}
+
+export class NewModelOperationParameters extends ModelOperationParameters implements INewModelOperationParameters {
+    riskControlTypes?: RiskControlType[] | undefined;
+    alpha?: number | undefined;
+    alphaInvestParameter?: AlphaInvestParameter | undefined;
+
+    constructor(data?: INewModelOperationParameters) {
+        super(data);
+        this._discriminator = "NewModelOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["RiskControlTypes"] && data["RiskControlTypes"].constructor === Array) {
+                this.riskControlTypes = [];
+                for (let item of data["RiskControlTypes"])
+                    this.riskControlTypes.push(item);
+            }
+            this.alpha = data["Alpha"];
+            this.alphaInvestParameter = data["AlphaInvestParameter"] ? AlphaInvestParameter.fromJS(data["AlphaInvestParameter"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): NewModelOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new NewModelOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.riskControlTypes && this.riskControlTypes.constructor === Array) {
+            data["RiskControlTypes"] = [];
+            for (let item of this.riskControlTypes)
+                data["RiskControlTypes"].push(item);
+        }
+        data["Alpha"] = this.alpha;
+        data["AlphaInvestParameter"] = this.alphaInvestParameter ? this.alphaInvestParameter.toJSON() : <any>undefined;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface INewModelOperationParameters extends IModelOperationParameters {
+    riskControlTypes?: RiskControlType[] | undefined;
+    alpha?: number | undefined;
+    alphaInvestParameter?: AlphaInvestParameter | undefined;
+}
+
+export class AlphaInvestParameter extends UniqueJson implements IAlphaInvestParameter {
+    beta?: number | undefined;
+    gamma?: number | undefined;
+    delta?: number | undefined;
+    epsilon?: number | undefined;
+    windowSize?: number | undefined;
+    psi?: number | undefined;
+
+    constructor(data?: IAlphaInvestParameter) {
+        super(data);
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.beta = data["Beta"];
+            this.gamma = data["Gamma"];
+            this.delta = data["Delta"];
+            this.epsilon = data["Epsilon"];
+            this.windowSize = data["WindowSize"];
+            this.psi = data["Psi"];
+        }
+    }
+
+    static fromJS(data: any): AlphaInvestParameter {
+        data = typeof data === 'object' ? data : {};
+        let result = new AlphaInvestParameter();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Beta"] = this.beta;
+        data["Gamma"] = this.gamma;
+        data["Delta"] = this.delta;
+        data["Epsilon"] = this.epsilon;
+        data["WindowSize"] = this.windowSize;
+        data["Psi"] = this.psi;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IAlphaInvestParameter extends IUniqueJson {
+    beta?: number | undefined;
+    gamma?: number | undefined;
+    delta?: number | undefined;
+    epsilon?: number | undefined;
+    windowSize?: number | undefined;
+    psi?: number | undefined;
+}
+
+export class RootMeanSquareTestOperationParameters extends HypothesisTestParameters implements IRootMeanSquareTestOperationParameters {
+    seeded?: boolean | undefined;
+    pValueConvergenceThreshold?: number | undefined;
+    maxSimulationBatchCount?: number | undefined;
+    perBatchSimulationCount?: number | undefined;
+
+    constructor(data?: IRootMeanSquareTestOperationParameters) {
+        super(data);
+        this._discriminator = "RootMeanSquareTestOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.seeded = data["Seeded"];
+            this.pValueConvergenceThreshold = data["PValueConvergenceThreshold"];
+            this.maxSimulationBatchCount = data["MaxSimulationBatchCount"];
+            this.perBatchSimulationCount = data["PerBatchSimulationCount"];
+        }
+    }
+
+    static fromJS(data: any): RootMeanSquareTestOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new RootMeanSquareTestOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Seeded"] = this.seeded;
+        data["PValueConvergenceThreshold"] = this.pValueConvergenceThreshold;
+        data["MaxSimulationBatchCount"] = this.maxSimulationBatchCount;
+        data["PerBatchSimulationCount"] = this.perBatchSimulationCount;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IRootMeanSquareTestOperationParameters extends IHypothesisTestParameters {
+    seeded?: boolean | undefined;
+    pValueConvergenceThreshold?: number | undefined;
+    maxSimulationBatchCount?: number | undefined;
+    perBatchSimulationCount?: number | undefined;
+}
+
+export class TTestOperationParameters extends HypothesisTestParameters implements ITTestOperationParameters {
+
+    constructor(data?: ITTestOperationParameters) {
+        super(data);
+        this._discriminator = "TTestOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): TTestOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new TTestOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ITTestOperationParameters extends IHypothesisTestParameters {
+}
+
+export enum EffectSize {
+    Small = 1,
+    Meduim = 2,
+    Large = 4,
+}
+
+export abstract class Result extends UniqueJson implements IResult {
+    progress?: number | undefined;
+
+    protected _discriminator: string;
+
+    constructor(data?: IResult) {
+        super(data);
+        this._discriminator = "Result";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.progress = data["Progress"];
+        }
+    }
+
+    static fromJS(data: any): Result {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "ErrorResult") {
+            let result = new ErrorResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "HistogramResult") {
+            let result = new HistogramResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "DistResult") {
+            throw new Error("The abstract class 'DistResult' cannot be instantiated.");
+        }
+        if (data["discriminator"] === "ModelWealthResult") {
+            let result = new ModelWealthResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "HypothesisTestResult") {
+            throw new Error("The abstract class 'HypothesisTestResult' cannot be instantiated.");
+        }
+        if (data["discriminator"] === "ModelOperationResult") {
+            throw new Error("The abstract class 'ModelOperationResult' cannot be instantiated.");
+        }
+        if (data["discriminator"] === "RecommenderResult") {
+            let result = new RecommenderResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "Decision") {
+            let result = new Decision();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "OptimizerResult") {
+            let result = new OptimizerResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "ExampleResult") {
+            let result = new ExampleResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "NewModelOperationResult") {
+            let result = new NewModelOperationResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "AddComparisonResult") {
+            let result = new AddComparisonResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "GetModelStateResult") {
+            let result = new GetModelStateResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "FeatureImportanceResult") {
+            let result = new FeatureImportanceResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "RawDataResult") {
+            let result = new RawDataResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "SampleResult") {
+            let result = new SampleResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "CDFResult") {
+            let result = new CDFResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "ChiSquaredTestResult") {
+            let result = new ChiSquaredTestResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "CorrelationTestResult") {
+            let result = new CorrelationTestResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "EmpiricalDistResult") {
+            let result = new EmpiricalDistResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "KSTestResult") {
+            let result = new KSTestResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "RootMeanSquareTestResult") {
+            let result = new RootMeanSquareTestResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "TTestResult") {
+            let result = new TTestResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "FrequentItemsetResult") {
+            let result = new FrequentItemsetResult();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'Result' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        data["Progress"] = this.progress;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IResult extends IUniqueJson {
+    progress?: number | undefined;
+}
+
+export class ErrorResult extends Result implements IErrorResult {
+    message?: string | undefined;
+
+    constructor(data?: IErrorResult) {
+        super(data);
+        this._discriminator = "ErrorResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.message = data["Message"];
+        }
+    }
+
+    static fromJS(data: any): ErrorResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new ErrorResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Message"] = this.message;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IErrorResult extends IResult {
+    message?: string | undefined;
+}
+
+export abstract class DistResult extends Result implements IDistResult {
+    sampleSize?: number | undefined;
+    populationSize?: number | undefined;
+
+    constructor(data?: IDistResult) {
+        super(data);
+        this._discriminator = "DistResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.sampleSize = data["SampleSize"];
+            this.populationSize = data["PopulationSize"];
+        }
+    }
+
+    static fromJS(data: any): DistResult {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "HistogramResult") {
+            let result = new HistogramResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "RawDataResult") {
+            let result = new RawDataResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "SampleResult") {
+            let result = new SampleResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "CDFResult") {
+            let result = new CDFResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "EmpiricalDistResult") {
+            let result = new EmpiricalDistResult();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'DistResult' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["SampleSize"] = this.sampleSize;
+        data["PopulationSize"] = this.populationSize;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IDistResult extends IResult {
+    sampleSize?: number | undefined;
+    populationSize?: number | undefined;
+}
+
+export class HistogramResult extends DistResult implements IHistogramResult {
+    aggregateResults?: AggregateResult[][] | undefined;
+    isEmpty?: boolean | undefined;
+    brushes?: Brush[] | undefined;
+    binRanges?: BinRange[] | undefined;
+    aggregateParameters?: AggregateParameters[] | undefined;
+    nullValueCount?: number | undefined;
+    bins?: { [key: string]: Bin; } | undefined;
+
+    constructor(data?: IHistogramResult) {
+        super(data);
+        this._discriminator = "HistogramResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["AggregateResults"] && data["AggregateResults"].constructor === Array) {
+                this.aggregateResults = [];
+                for (let item of data["AggregateResults"])
+                    this.aggregateResults.push(item);
+            }
+            this.isEmpty = data["IsEmpty"];
+            if (data["Brushes"] && data["Brushes"].constructor === Array) {
+                this.brushes = [];
+                for (let item of data["Brushes"])
+                    this.brushes.push(Brush.fromJS(item));
+            }
+            if (data["BinRanges"] && data["BinRanges"].constructor === Array) {
+                this.binRanges = [];
+                for (let item of data["BinRanges"])
+                    this.binRanges.push(BinRange.fromJS(item));
+            }
+            if (data["AggregateParameters"] && data["AggregateParameters"].constructor === Array) {
+                this.aggregateParameters = [];
+                for (let item of data["AggregateParameters"])
+                    this.aggregateParameters.push(AggregateParameters.fromJS(item));
+            }
+            this.nullValueCount = data["NullValueCount"];
+            if (data["Bins"]) {
+                this.bins = {};
+                for (let key in data["Bins"]) {
+                    if (data["Bins"].hasOwnProperty(key))
+                        this.bins[key] = data["Bins"][key] ? Bin.fromJS(data["Bins"][key]) : new Bin();
+                }
+            }
+        }
+    }
+
+    static fromJS(data: any): HistogramResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new HistogramResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.aggregateResults && this.aggregateResults.constructor === Array) {
+            data["AggregateResults"] = [];
+            for (let item of this.aggregateResults)
+                data["AggregateResults"].push(item);
+        }
+        data["IsEmpty"] = this.isEmpty;
+        if (this.brushes && this.brushes.constructor === Array) {
+            data["Brushes"] = [];
+            for (let item of this.brushes)
+                data["Brushes"].push(item.toJSON());
+        }
+        if (this.binRanges && this.binRanges.constructor === Array) {
+            data["BinRanges"] = [];
+            for (let item of this.binRanges)
+                data["BinRanges"].push(item.toJSON());
+        }
+        if (this.aggregateParameters && this.aggregateParameters.constructor === Array) {
+            data["AggregateParameters"] = [];
+            for (let item of this.aggregateParameters)
+                data["AggregateParameters"].push(item.toJSON());
+        }
+        data["NullValueCount"] = this.nullValueCount;
+        if (this.bins) {
+            data["Bins"] = {};
+            for (let key in this.bins) {
+                if (this.bins.hasOwnProperty(key))
+                    data["Bins"][key] = this.bins[key];
+            }
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IHistogramResult extends IDistResult {
+    aggregateResults?: AggregateResult[][] | undefined;
+    isEmpty?: boolean | undefined;
+    brushes?: Brush[] | undefined;
+    binRanges?: BinRange[] | undefined;
+    aggregateParameters?: AggregateParameters[] | undefined;
+    nullValueCount?: number | undefined;
+    bins?: { [key: string]: Bin; } | undefined;
+}
+
+export abstract class AggregateResult implements IAggregateResult {
+    hasResult?: boolean | undefined;
+    n?: number | undefined;
+
+    protected _discriminator: string;
+
+    constructor(data?: IAggregateResult) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+        this._discriminator = "AggregateResult";
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.hasResult = data["HasResult"];
+            this.n = data["N"];
+        }
+    }
+
+    static fromJS(data: any): AggregateResult | undefined {
+        if (data === null || data === undefined) {
+            return undefined;
+        }
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "MarginAggregateResult") {
+            let result = new MarginAggregateResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "DoubleValueAggregateResult") {
+            let result = new DoubleValueAggregateResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "PointsAggregateResult") {
+            let result = new PointsAggregateResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "SumEstimationAggregateResult") {
+            let result = new SumEstimationAggregateResult();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'AggregateResult' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        data["HasResult"] = this.hasResult;
+        data["N"] = this.n;
+        return data;
+    }
+}
+
+export interface IAggregateResult {
+    hasResult?: boolean | undefined;
+    n?: number | undefined;
+}
+
+export class MarginAggregateResult extends AggregateResult implements IMarginAggregateResult {
+    margin?: number | undefined;
+    absolutMargin?: number | undefined;
+    sumOfSquare?: number | undefined;
+    sampleStandardDeviation?: number | undefined;
+    mean?: number | undefined;
+    ex?: number | undefined;
+    ex2?: number | undefined;
+    variance?: number | undefined;
+
+    constructor(data?: IMarginAggregateResult) {
+        super(data);
+        this._discriminator = "MarginAggregateResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.margin = data["Margin"];
+            this.absolutMargin = data["AbsolutMargin"];
+            this.sumOfSquare = data["SumOfSquare"];
+            this.sampleStandardDeviation = data["SampleStandardDeviation"];
+            this.mean = data["Mean"];
+            this.ex = data["Ex"];
+            this.ex2 = data["Ex2"];
+            this.variance = data["Variance"];
+        }
+    }
+
+    static fromJS(data: any): MarginAggregateResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new MarginAggregateResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Margin"] = this.margin;
+        data["AbsolutMargin"] = this.absolutMargin;
+        data["SumOfSquare"] = this.sumOfSquare;
+        data["SampleStandardDeviation"] = this.sampleStandardDeviation;
+        data["Mean"] = this.mean;
+        data["Ex"] = this.ex;
+        data["Ex2"] = this.ex2;
+        data["Variance"] = this.variance;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IMarginAggregateResult extends IAggregateResult {
+    margin?: number | undefined;
+    absolutMargin?: number | undefined;
+    sumOfSquare?: number | undefined;
+    sampleStandardDeviation?: number | undefined;
+    mean?: number | undefined;
+    ex?: number | undefined;
+    ex2?: number | undefined;
+    variance?: number | undefined;
+}
+
+export class DoubleValueAggregateResult extends AggregateResult implements IDoubleValueAggregateResult {
+    result?: number | undefined;
+    temporaryResult?: number | undefined;
+
+    constructor(data?: IDoubleValueAggregateResult) {
+        super(data);
+        this._discriminator = "DoubleValueAggregateResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.result = data["Result"];
+            this.temporaryResult = data["TemporaryResult"];
+        }
+    }
+
+    static fromJS(data: any): DoubleValueAggregateResult {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "SumEstimationAggregateResult") {
+            let result = new SumEstimationAggregateResult();
+            result.init(data);
+            return result;
+        }
+        let result = new DoubleValueAggregateResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Result"] = this.result;
+        data["TemporaryResult"] = this.temporaryResult;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IDoubleValueAggregateResult extends IAggregateResult {
+    result?: number | undefined;
+    temporaryResult?: number | undefined;
+}
+
+export class PointsAggregateResult extends AggregateResult implements IPointsAggregateResult {
+    points?: Point[] | undefined;
+
+    constructor(data?: IPointsAggregateResult) {
+        super(data);
+        this._discriminator = "PointsAggregateResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["Points"] && data["Points"].constructor === Array) {
+                this.points = [];
+                for (let item of data["Points"])
+                    this.points.push(Point.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): PointsAggregateResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new PointsAggregateResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.points && this.points.constructor === Array) {
+            data["Points"] = [];
+            for (let item of this.points)
+                data["Points"].push(item.toJSON());
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IPointsAggregateResult extends IAggregateResult {
+    points?: Point[] | undefined;
+}
+
+export class Point implements IPoint {
+    x?: number | undefined;
+    y?: number | undefined;
+
+    constructor(data?: IPoint) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.x = data["X"];
+            this.y = data["Y"];
+        }
+    }
+
+    static fromJS(data: any): Point {
+        data = typeof data === 'object' ? data : {};
+        let result = new Point();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["X"] = this.x;
+        data["Y"] = this.y;
+        return data;
+    }
+}
+
+export interface IPoint {
+    x?: number | undefined;
+    y?: number | undefined;
+}
+
+export class SumEstimationAggregateResult extends DoubleValueAggregateResult implements ISumEstimationAggregateResult {
+    sum?: number | undefined;
+    sumEstimation?: number | undefined;
+
+    constructor(data?: ISumEstimationAggregateResult) {
+        super(data);
+        this._discriminator = "SumEstimationAggregateResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.sum = data["Sum"];
+            this.sumEstimation = data["SumEstimation"];
+        }
+    }
+
+    static fromJS(data: any): SumEstimationAggregateResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new SumEstimationAggregateResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Sum"] = this.sum;
+        data["SumEstimation"] = this.sumEstimation;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ISumEstimationAggregateResult extends IDoubleValueAggregateResult {
+    sum?: number | undefined;
+    sumEstimation?: number | undefined;
+}
+
+export class Brush implements IBrush {
+    brushIndex?: number | undefined;
+    brushEnum?: BrushEnum | undefined;
+
+    constructor(data?: IBrush) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.brushIndex = data["BrushIndex"];
+            this.brushEnum = data["BrushEnum"];
+        }
+    }
+
+    static fromJS(data: any): Brush {
+        data = typeof data === 'object' ? data : {};
+        let result = new Brush();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["BrushIndex"] = this.brushIndex;
+        data["BrushEnum"] = this.brushEnum;
+        return data;
+    }
+}
+
+export interface IBrush {
+    brushIndex?: number | undefined;
+    brushEnum?: BrushEnum | undefined;
+}
+
+export enum BrushEnum {
+    Overlap = 0,
+    Rest = 1,
+    All = 2,
+    UserSpecified = 3,
+}
+
+export abstract class BinRange implements IBinRange {
+    minValue?: number | undefined;
+    maxValue?: number | undefined;
+    targetBinNumber?: number | undefined;
+
+    protected _discriminator: string;
+
+    constructor(data?: IBinRange) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+        this._discriminator = "BinRange";
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.minValue = data["MinValue"];
+            this.maxValue = data["MaxValue"];
+            this.targetBinNumber = data["TargetBinNumber"];
+        }
+    }
+
+    static fromJS(data: any): BinRange {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "NominalBinRange") {
+            let result = new NominalBinRange();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "QuantitativeBinRange") {
+            let result = new QuantitativeBinRange();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "AggregateBinRange") {
+            let result = new AggregateBinRange();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "AlphabeticBinRange") {
+            let result = new AlphabeticBinRange();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "DateTimeBinRange") {
+            let result = new DateTimeBinRange();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'BinRange' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        data["MinValue"] = this.minValue;
+        data["MaxValue"] = this.maxValue;
+        data["TargetBinNumber"] = this.targetBinNumber;
+        return data;
+    }
+}
+
+export interface IBinRange {
+    minValue?: number | undefined;
+    maxValue?: number | undefined;
+    targetBinNumber?: number | undefined;
+}
+
+export class NominalBinRange extends BinRange implements INominalBinRange {
+    labelsValue?: { [key: string]: number; } | undefined;
+    valuesLabel?: { [key: string]: string; } | undefined;
+
+    constructor(data?: INominalBinRange) {
+        super(data);
+        this._discriminator = "NominalBinRange";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["LabelsValue"]) {
+                this.labelsValue = {};
+                for (let key in data["LabelsValue"]) {
+                    if (data["LabelsValue"].hasOwnProperty(key))
+                        this.labelsValue[key] = data["LabelsValue"][key];
+                }
+            }
+            if (data["ValuesLabel"]) {
+                this.valuesLabel = {};
+                for (let key in data["ValuesLabel"]) {
+                    if (data["ValuesLabel"].hasOwnProperty(key))
+                        this.valuesLabel[key] = data["ValuesLabel"][key];
+                }
+            }
+        }
+    }
+
+    static fromJS(data: any): NominalBinRange {
+        data = typeof data === 'object' ? data : {};
+        let result = new NominalBinRange();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.labelsValue) {
+            data["LabelsValue"] = {};
+            for (let key in this.labelsValue) {
+                if (this.labelsValue.hasOwnProperty(key))
+                    data["LabelsValue"][key] = this.labelsValue[key];
+            }
+        }
+        if (this.valuesLabel) {
+            data["ValuesLabel"] = {};
+            for (let key in this.valuesLabel) {
+                if (this.valuesLabel.hasOwnProperty(key))
+                    data["ValuesLabel"][key] = this.valuesLabel[key];
+            }
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface INominalBinRange extends IBinRange {
+    labelsValue?: { [key: string]: number; } | undefined;
+    valuesLabel?: { [key: string]: string; } | undefined;
+}
+
+export class QuantitativeBinRange extends BinRange implements IQuantitativeBinRange {
+    isIntegerRange?: boolean | undefined;
+    step?: number | undefined;
+
+    constructor(data?: IQuantitativeBinRange) {
+        super(data);
+        this._discriminator = "QuantitativeBinRange";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.isIntegerRange = data["IsIntegerRange"];
+            this.step = data["Step"];
+        }
+    }
+
+    static fromJS(data: any): QuantitativeBinRange {
+        data = typeof data === 'object' ? data : {};
+        let result = new QuantitativeBinRange();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["IsIntegerRange"] = this.isIntegerRange;
+        data["Step"] = this.step;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IQuantitativeBinRange extends IBinRange {
+    isIntegerRange?: boolean | undefined;
+    step?: number | undefined;
+}
+
+export class AggregateBinRange extends BinRange implements IAggregateBinRange {
+
+    constructor(data?: IAggregateBinRange) {
+        super(data);
+        this._discriminator = "AggregateBinRange";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): AggregateBinRange {
+        data = typeof data === 'object' ? data : {};
+        let result = new AggregateBinRange();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IAggregateBinRange extends IBinRange {
+}
+
+export class AlphabeticBinRange extends BinRange implements IAlphabeticBinRange {
+    prefix?: string | undefined;
+    labelsValue?: { [key: string]: number; } | undefined;
+    valuesLabel?: { [key: string]: string; } | undefined;
+
+    constructor(data?: IAlphabeticBinRange) {
+        super(data);
+        this._discriminator = "AlphabeticBinRange";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.prefix = data["Prefix"];
+            if (data["LabelsValue"]) {
+                this.labelsValue = {};
+                for (let key in data["LabelsValue"]) {
+                    if (data["LabelsValue"].hasOwnProperty(key))
+                        this.labelsValue[key] = data["LabelsValue"][key];
+                }
+            }
+            if (data["ValuesLabel"]) {
+                this.valuesLabel = {};
+                for (let key in data["ValuesLabel"]) {
+                    if (data["ValuesLabel"].hasOwnProperty(key))
+                        this.valuesLabel[key] = data["ValuesLabel"][key];
+                }
+            }
+        }
+    }
+
+    static fromJS(data: any): AlphabeticBinRange {
+        data = typeof data === 'object' ? data : {};
+        let result = new AlphabeticBinRange();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Prefix"] = this.prefix;
+        if (this.labelsValue) {
+            data["LabelsValue"] = {};
+            for (let key in this.labelsValue) {
+                if (this.labelsValue.hasOwnProperty(key))
+                    data["LabelsValue"][key] = this.labelsValue[key];
+            }
+        }
+        if (this.valuesLabel) {
+            data["ValuesLabel"] = {};
+            for (let key in this.valuesLabel) {
+                if (this.valuesLabel.hasOwnProperty(key))
+                    data["ValuesLabel"][key] = this.valuesLabel[key];
+            }
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IAlphabeticBinRange extends IBinRange {
+    prefix?: string | undefined;
+    labelsValue?: { [key: string]: number; } | undefined;
+    valuesLabel?: { [key: string]: string; } | undefined;
+}
+
+export class DateTimeBinRange extends BinRange implements IDateTimeBinRange {
+    step?: DateTimeStep | undefined;
+
+    constructor(data?: IDateTimeBinRange) {
+        super(data);
+        this._discriminator = "DateTimeBinRange";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.step = data["Step"] ? DateTimeStep.fromJS(data["Step"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): DateTimeBinRange {
+        data = typeof data === 'object' ? data : {};
+        let result = new DateTimeBinRange();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Step"] = this.step ? this.step.toJSON() : <any>undefined;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IDateTimeBinRange extends IBinRange {
+    step?: DateTimeStep | undefined;
+}
+
+export class DateTimeStep implements IDateTimeStep {
+    dateTimeStepGranularity?: DateTimeStepGranularity | undefined;
+    dateTimeStepValue?: number | undefined;
+    dateTimeStepMaxValue?: number | undefined;
+
+    constructor(data?: IDateTimeStep) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.dateTimeStepGranularity = data["DateTimeStepGranularity"];
+            this.dateTimeStepValue = data["DateTimeStepValue"];
+            this.dateTimeStepMaxValue = data["DateTimeStepMaxValue"];
+        }
+    }
+
+    static fromJS(data: any): DateTimeStep {
+        data = typeof data === 'object' ? data : {};
+        let result = new DateTimeStep();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["DateTimeStepGranularity"] = this.dateTimeStepGranularity;
+        data["DateTimeStepValue"] = this.dateTimeStepValue;
+        data["DateTimeStepMaxValue"] = this.dateTimeStepMaxValue;
+        return data;
+    }
+}
+
+export interface IDateTimeStep {
+    dateTimeStepGranularity?: DateTimeStepGranularity | undefined;
+    dateTimeStepValue?: number | undefined;
+    dateTimeStepMaxValue?: number | undefined;
+}
+
+export enum DateTimeStepGranularity {
+    Second = 0,
+    Minute = 1,
+    Hour = 2,
+    Day = 3,
+    Month = 4,
+    Year = 5,
+}
+
+export class Bin implements IBin {
+    aggregateResults?: AggregateResult[] | undefined;
+    count?: number | undefined;
+    binIndex?: BinIndex | undefined;
+    spans?: Span[] | undefined;
+    xSize?: number | undefined;
+    ySize?: number | undefined;
+
+    constructor(data?: IBin) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            if (data["AggregateResults"] && data["AggregateResults"].constructor === Array) {
+                this.aggregateResults = [];
+                for (let item of data["AggregateResults"]) {
+                    let fromJs = AggregateResult.fromJS(item);
+                    if (fromJs)
+                        this.aggregateResults.push(fromJs);
+                }
+            }
+            this.count = data["Count"];
+            this.binIndex = data["BinIndex"] ? BinIndex.fromJS(data["BinIndex"]) : <any>undefined;
+            if (data["Spans"] && data["Spans"].constructor === Array) {
+                this.spans = [];
+                for (let item of data["Spans"])
+                    this.spans.push(Span.fromJS(item));
+            }
+            this.xSize = data["XSize"];
+            this.ySize = data["YSize"];
+        }
+    }
+
+    static fromJS(data: any): Bin {
+        data = typeof data === 'object' ? data : {};
+        let result = new Bin();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.aggregateResults && this.aggregateResults.constructor === Array) {
+            data["AggregateResults"] = [];
+            for (let item of this.aggregateResults)
+                data["AggregateResults"].push(item.toJSON());
+        }
+        data["Count"] = this.count;
+        data["BinIndex"] = this.binIndex ? this.binIndex.toJSON() : <any>undefined;
+        if (this.spans && this.spans.constructor === Array) {
+            data["Spans"] = [];
+            for (let item of this.spans)
+                data["Spans"].push(item.toJSON());
+        }
+        data["XSize"] = this.xSize;
+        data["YSize"] = this.ySize;
+        return data;
+    }
+}
+
+export interface IBin {
+    aggregateResults?: AggregateResult[] | undefined;
+    count?: number | undefined;
+    binIndex?: BinIndex | undefined;
+    spans?: Span[] | undefined;
+    xSize?: number | undefined;
+    ySize?: number | undefined;
+}
+
+export class BinIndex implements IBinIndex {
+    indices?: number[] | undefined;
+    flatIndex?: number | undefined;
+
+    constructor(data?: IBinIndex) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            if (data["Indices"] && data["Indices"].constructor === Array) {
+                this.indices = [];
+                for (let item of data["Indices"])
+                    this.indices.push(item);
+            }
+            this.flatIndex = data["FlatIndex"];
+        }
+    }
+
+    static fromJS(data: any): BinIndex {
+        data = typeof data === 'object' ? data : {};
+        let result = new BinIndex();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.indices && this.indices.constructor === Array) {
+            data["Indices"] = [];
+            for (let item of this.indices)
+                data["Indices"].push(item);
+        }
+        data["FlatIndex"] = this.flatIndex;
+        return data;
+    }
+}
+
+export interface IBinIndex {
+    indices?: number[] | undefined;
+    flatIndex?: number | undefined;
+}
+
+export class Span implements ISpan {
+    min?: number | undefined;
+    max?: number | undefined;
+    index?: number | undefined;
+
+    constructor(data?: ISpan) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.min = data["Min"];
+            this.max = data["Max"];
+            this.index = data["Index"];
+        }
+    }
+
+    static fromJS(data: any): Span {
+        data = typeof data === 'object' ? data : {};
+        let result = new Span();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Min"] = this.min;
+        data["Max"] = this.max;
+        data["Index"] = this.index;
+        return data;
+    }
+}
+
+export interface ISpan {
+    min?: number | undefined;
+    max?: number | undefined;
+    index?: number | undefined;
+}
+
+export class ModelWealthResult extends Result implements IModelWealthResult {
+    wealth?: number | undefined;
+    startWealth?: number | undefined;
+
+    constructor(data?: IModelWealthResult) {
+        super(data);
+        this._discriminator = "ModelWealthResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.wealth = data["Wealth"];
+            this.startWealth = data["StartWealth"];
+        }
+    }
+
+    static fromJS(data: any): ModelWealthResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new ModelWealthResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Wealth"] = this.wealth;
+        data["StartWealth"] = this.startWealth;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IModelWealthResult extends IResult {
+    wealth?: number | undefined;
+    startWealth?: number | undefined;
+}
+
+export abstract class HypothesisTestResult extends Result implements IHypothesisTestResult {
+    pValue?: number | undefined;
+    statistic?: number | undefined;
+    support?: number | undefined;
+    sampleSizes?: number[] | undefined;
+    errorMessage?: string | undefined;
+
+    constructor(data?: IHypothesisTestResult) {
+        super(data);
+        this._discriminator = "HypothesisTestResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.pValue = data["PValue"];
+            this.statistic = data["Statistic"];
+            this.support = data["Support"];
+            if (data["SampleSizes"] && data["SampleSizes"].constructor === Array) {
+                this.sampleSizes = [];
+                for (let item of data["SampleSizes"])
+                    this.sampleSizes.push(item);
+            }
+            this.errorMessage = data["ErrorMessage"];
+        }
+    }
+
+    static fromJS(data: any): HypothesisTestResult {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "ChiSquaredTestResult") {
+            let result = new ChiSquaredTestResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "CorrelationTestResult") {
+            let result = new CorrelationTestResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "KSTestResult") {
+            let result = new KSTestResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "RootMeanSquareTestResult") {
+            let result = new RootMeanSquareTestResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "TTestResult") {
+            let result = new TTestResult();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'HypothesisTestResult' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["PValue"] = this.pValue;
+        data["Statistic"] = this.statistic;
+        data["Support"] = this.support;
+        if (this.sampleSizes && this.sampleSizes.constructor === Array) {
+            data["SampleSizes"] = [];
+            for (let item of this.sampleSizes)
+                data["SampleSizes"].push(item);
+        }
+        data["ErrorMessage"] = this.errorMessage;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IHypothesisTestResult extends IResult {
+    pValue?: number | undefined;
+    statistic?: number | undefined;
+    support?: number | undefined;
+    sampleSizes?: number[] | undefined;
+    errorMessage?: string | undefined;
+}
+
+export abstract class ModelOperationResult extends Result implements IModelOperationResult {
+    modelId?: ModelId | undefined;
+
+    constructor(data?: IModelOperationResult) {
+        super(data);
+        this._discriminator = "ModelOperationResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.modelId = data["ModelId"] ? ModelId.fromJS(data["ModelId"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): ModelOperationResult {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "NewModelOperationResult") {
+            let result = new NewModelOperationResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "AddComparisonResult") {
+            let result = new AddComparisonResult();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "GetModelStateResult") {
+            let result = new GetModelStateResult();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'ModelOperationResult' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["ModelId"] = this.modelId ? this.modelId.toJSON() : <any>undefined;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IModelOperationResult extends IResult {
+    modelId?: ModelId | undefined;
+}
+
+export class RecommenderResult extends Result implements IRecommenderResult {
+    recommendedHistograms?: RecommendedHistogram[] | undefined;
+    totalCount?: number | undefined;
+
+    constructor(data?: IRecommenderResult) {
+        super(data);
+        this._discriminator = "RecommenderResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["RecommendedHistograms"] && data["RecommendedHistograms"].constructor === Array) {
+                this.recommendedHistograms = [];
+                for (let item of data["RecommendedHistograms"])
+                    this.recommendedHistograms.push(RecommendedHistogram.fromJS(item));
+            }
+            this.totalCount = data["TotalCount"];
+        }
+    }
+
+    static fromJS(data: any): RecommenderResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new RecommenderResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.recommendedHistograms && this.recommendedHistograms.constructor === Array) {
+            data["RecommendedHistograms"] = [];
+            for (let item of this.recommendedHistograms)
+                data["RecommendedHistograms"].push(item.toJSON());
+        }
+        data["TotalCount"] = this.totalCount;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IRecommenderResult extends IResult {
+    recommendedHistograms?: RecommendedHistogram[] | undefined;
+    totalCount?: number | undefined;
+}
+
+export class RecommendedHistogram implements IRecommendedHistogram {
+    histogramResult?: HistogramResult | undefined;
+    selectedBinIndices?: BinIndex[] | undefined;
+    selections?: Selection[] | undefined;
+    pValue?: number | undefined;
+    significance?: boolean | undefined;
+    decision?: Decision | undefined;
+    effectSize?: number | undefined;
+    hypothesisTestResult?: HypothesisTestResult | undefined;
+    id?: string | undefined;
+    xAttribute?: Attribute | undefined;
+    yAttribute?: Attribute | undefined;
+
+    constructor(data?: IRecommendedHistogram) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.histogramResult = data["HistogramResult"] ? HistogramResult.fromJS(data["HistogramResult"]) : <any>undefined;
+            if (data["SelectedBinIndices"] && data["SelectedBinIndices"].constructor === Array) {
+                this.selectedBinIndices = [];
+                for (let item of data["SelectedBinIndices"])
+                    this.selectedBinIndices.push(BinIndex.fromJS(item));
+            }
+            if (data["Selections"] && data["Selections"].constructor === Array) {
+                this.selections = [];
+                for (let item of data["Selections"])
+                    this.selections.push(Selection.fromJS(item));
+            }
+            this.pValue = data["PValue"];
+            this.significance = data["Significance"];
+            this.decision = data["Decision"] ? Decision.fromJS(data["Decision"]) : <any>undefined;
+            this.effectSize = data["EffectSize"];
+            this.hypothesisTestResult = data["HypothesisTestResult"] ? HypothesisTestResult.fromJS(data["HypothesisTestResult"]) : <any>undefined;
+            this.id = data["Id"];
+            this.xAttribute = data["XAttribute"] ? Attribute.fromJS(data["XAttribute"]) : <any>undefined;
+            this.yAttribute = data["YAttribute"] ? Attribute.fromJS(data["YAttribute"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): RecommendedHistogram {
+        data = typeof data === 'object' ? data : {};
+        let result = new RecommendedHistogram();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["HistogramResult"] = this.histogramResult ? this.histogramResult.toJSON() : <any>undefined;
+        if (this.selectedBinIndices && this.selectedBinIndices.constructor === Array) {
+            data["SelectedBinIndices"] = [];
+            for (let item of this.selectedBinIndices)
+                data["SelectedBinIndices"].push(item.toJSON());
+        }
+        if (this.selections && this.selections.constructor === Array) {
+            data["Selections"] = [];
+            for (let item of this.selections)
+                data["Selections"].push(item.toJSON());
+        }
+        data["PValue"] = this.pValue;
+        data["Significance"] = this.significance;
+        data["Decision"] = this.decision ? this.decision.toJSON() : <any>undefined;
+        data["EffectSize"] = this.effectSize;
+        data["HypothesisTestResult"] = this.hypothesisTestResult ? this.hypothesisTestResult.toJSON() : <any>undefined;
+        data["Id"] = this.id;
+        data["XAttribute"] = this.xAttribute ? this.xAttribute.toJSON() : <any>undefined;
+        data["YAttribute"] = this.yAttribute ? this.yAttribute.toJSON() : <any>undefined;
+        return data;
+    }
+}
+
+export interface IRecommendedHistogram {
+    histogramResult?: HistogramResult | undefined;
+    selectedBinIndices?: BinIndex[] | undefined;
+    selections?: Selection[] | undefined;
+    pValue?: number | undefined;
+    significance?: boolean | undefined;
+    decision?: Decision | undefined;
+    effectSize?: number | undefined;
+    hypothesisTestResult?: HypothesisTestResult | undefined;
+    id?: string | undefined;
+    xAttribute?: Attribute | undefined;
+    yAttribute?: Attribute | undefined;
+}
+
+export class Selection implements ISelection {
+    statements?: Statement[] | undefined;
+    filterHistogramOperationReference?: IOperationReference | undefined;
+
+    constructor(data?: ISelection) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            if (data["Statements"] && data["Statements"].constructor === Array) {
+                this.statements = [];
+                for (let item of data["Statements"])
+                    this.statements.push(Statement.fromJS(item));
+            }
+            this.filterHistogramOperationReference = data["FilterHistogramOperationReference"] ? IOperationReference.fromJS(data["FilterHistogramOperationReference"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): Selection {
+        data = typeof data === 'object' ? data : {};
+        let result = new Selection();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.statements && this.statements.constructor === Array) {
+            data["Statements"] = [];
+            for (let item of this.statements)
+                data["Statements"].push(item.toJSON());
+        }
+        data["FilterHistogramOperationReference"] = this.filterHistogramOperationReference ? this.filterHistogramOperationReference.toJSON() : <any>undefined;
+        return data;
+    }
+}
+
+export interface ISelection {
+    statements?: Statement[] | undefined;
+    filterHistogramOperationReference?: IOperationReference | undefined;
+}
+
+export class Statement implements IStatement {
+    attribute?: Attribute | undefined;
+    predicate?: Predicate | undefined;
+    value?: any | undefined;
+
+    constructor(data?: IStatement) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.attribute = data["Attribute"] ? Attribute.fromJS(data["Attribute"]) : <any>undefined;
+            this.predicate = data["Predicate"];
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): Statement {
+        data = typeof data === 'object' ? data : {};
+        let result = new Statement();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Attribute"] = this.attribute ? this.attribute.toJSON() : <any>undefined;
+        data["Predicate"] = this.predicate;
+        data["Value"] = this.value;
+        return data;
+    }
+}
+
+export interface IStatement {
+    attribute?: Attribute | undefined;
+    predicate?: Predicate | undefined;
+    value?: any | undefined;
+}
+
+export enum Predicate {
+    EQUALS = 0,
+    LIKE = 1,
+    GREATER_THAN = 2,
+    LESS_THAN = 3,
+    GREATER_THAN_EQUAL = 4,
+    LESS_THAN_EQUAL = 5,
+    STARTS_WITH = 6,
+    ENDS_WITH = 7,
+    CONTAINS = 8,
+}
+
+export abstract class IOperationReference implements IIOperationReference {
+    id?: string | undefined;
+
+    protected _discriminator: string;
+
+    constructor(data?: IIOperationReference) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+        this._discriminator = "IOperationReference";
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.id = data["Id"];
+        }
+    }
+
+    static fromJS(data: any): IOperationReference {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "OperationReference") {
+            let result = new OperationReference();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'IOperationReference' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        data["Id"] = this.id;
+        return data;
+    }
+}
+
+export interface IIOperationReference {
+    id?: string | undefined;
+}
+
+export class OperationReference extends IOperationReference implements IOperationReference {
+    id?: string | undefined;
+
+    constructor(data?: IOperationReference) {
+        super(data);
+        this._discriminator = "OperationReference";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.id = data["Id"];
+        }
+    }
+
+    static fromJS(data: any): OperationReference {
+        data = typeof data === 'object' ? data : {};
+        let result = new OperationReference();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Id"] = this.id;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IOperationReference extends IIOperationReference {
+    id?: string | undefined;
+}
+
+export class Decision extends Result implements IDecision {
+    comparisonId?: ComparisonId | undefined;
+    riskControlType?: RiskControlType | undefined;
+    significance?: boolean | undefined;
+    pValue?: number | undefined;
+    lhs?: number | undefined;
+    significanceLevel?: number | undefined;
+    sampleSizeEstimate?: number | undefined;
+
+    constructor(data?: IDecision) {
+        super(data);
+        this._discriminator = "Decision";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.comparisonId = data["ComparisonId"] ? ComparisonId.fromJS(data["ComparisonId"]) : <any>undefined;
+            this.riskControlType = data["RiskControlType"];
+            this.significance = data["Significance"];
+            this.pValue = data["PValue"];
+            this.lhs = data["Lhs"];
+            this.significanceLevel = data["SignificanceLevel"];
+            this.sampleSizeEstimate = data["SampleSizeEstimate"];
+        }
+    }
+
+    static fromJS(data: any): Decision {
+        data = typeof data === 'object' ? data : {};
+        let result = new Decision();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["ComparisonId"] = this.comparisonId ? this.comparisonId.toJSON() : <any>undefined;
+        data["RiskControlType"] = this.riskControlType;
+        data["Significance"] = this.significance;
+        data["PValue"] = this.pValue;
+        data["Lhs"] = this.lhs;
+        data["SignificanceLevel"] = this.significanceLevel;
+        data["SampleSizeEstimate"] = this.sampleSizeEstimate;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IDecision extends IResult {
+    comparisonId?: ComparisonId | undefined;
+    riskControlType?: RiskControlType | undefined;
+    significance?: boolean | undefined;
+    pValue?: number | undefined;
+    lhs?: number | undefined;
+    significanceLevel?: number | undefined;
+    sampleSizeEstimate?: number | undefined;
+}
+
+export class ComparisonId implements IComparisonId {
+    value?: string | undefined;
+
+    constructor(data?: IComparisonId) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): ComparisonId {
+        data = typeof data === 'object' ? data : {};
+        let result = new ComparisonId();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        return data;
+    }
+}
+
+export interface IComparisonId {
+    value?: string | undefined;
+}
+
+export class OptimizerResult extends Result implements IOptimizerResult {
+    topKSolutions?: Solution[] | undefined;
+
+    constructor(data?: IOptimizerResult) {
+        super(data);
+        this._discriminator = "OptimizerResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["TopKSolutions"] && data["TopKSolutions"].constructor === Array) {
+                this.topKSolutions = [];
+                for (let item of data["TopKSolutions"])
+                    this.topKSolutions.push(Solution.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): OptimizerResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new OptimizerResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.topKSolutions && this.topKSolutions.constructor === Array) {
+            data["TopKSolutions"] = [];
+            for (let item of this.topKSolutions)
+                data["TopKSolutions"].push(item.toJSON());
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IOptimizerResult extends IResult {
+    topKSolutions?: Solution[] | undefined;
+}
+
+export class Solution implements ISolution {
+    solutionId?: string | undefined;
+    stepDescriptions?: StepDescription[] | undefined;
+    pipelineDescription?: PipelineDescription | undefined;
+    score?: Score | undefined;
+    naiveScore?: Score | undefined;
+
+    constructor(data?: ISolution) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.solutionId = data["SolutionId"];
+            if (data["StepDescriptions"] && data["StepDescriptions"].constructor === Array) {
+                this.stepDescriptions = [];
+                for (let item of data["StepDescriptions"])
+                    this.stepDescriptions.push(StepDescription.fromJS(item));
+            }
+            this.pipelineDescription = data["PipelineDescription"] ? PipelineDescription.fromJS(data["PipelineDescription"]) : <any>undefined;
+            this.score = data["Score"] ? Score.fromJS(data["Score"]) : <any>undefined;
+            this.naiveScore = data["NaiveScore"] ? Score.fromJS(data["NaiveScore"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): Solution {
+        data = typeof data === 'object' ? data : {};
+        let result = new Solution();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["SolutionId"] = this.solutionId;
+        if (this.stepDescriptions && this.stepDescriptions.constructor === Array) {
+            data["StepDescriptions"] = [];
+            for (let item of this.stepDescriptions)
+                data["StepDescriptions"].push(item.toJSON());
+        }
+        data["PipelineDescription"] = this.pipelineDescription ? this.pipelineDescription.toJSON() : <any>undefined;
+        data["Score"] = this.score ? this.score.toJSON() : <any>undefined;
+        data["NaiveScore"] = this.naiveScore ? this.naiveScore.toJSON() : <any>undefined;
+        return data;
+    }
+}
+
+export interface ISolution {
+    solutionId?: string | undefined;
+    stepDescriptions?: StepDescription[] | undefined;
+    pipelineDescription?: PipelineDescription | undefined;
+    score?: Score | undefined;
+    naiveScore?: Score | undefined;
+}
+
+export class StepDescription implements IStepDescription {
+
+    protected _discriminator: string;
+
+    constructor(data?: IStepDescription) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+        this._discriminator = "StepDescription";
+    }
+
+    init(data?: any) {
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): StepDescription {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "SubpipelineStepDescription") {
+            let result = new SubpipelineStepDescription();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "PrimitiveStepDescription") {
+            let result = new PrimitiveStepDescription();
+            result.init(data);
+            return result;
+        }
+        let result = new StepDescription();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        return data;
+    }
+}
+
+export interface IStepDescription {
+}
+
+export class SubpipelineStepDescription extends StepDescription implements ISubpipelineStepDescription {
+    steps?: StepDescription[] | undefined;
+
+    constructor(data?: ISubpipelineStepDescription) {
+        super(data);
+        this._discriminator = "SubpipelineStepDescription";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["Steps"] && data["Steps"].constructor === Array) {
+                this.steps = [];
+                for (let item of data["Steps"])
+                    this.steps.push(StepDescription.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): SubpipelineStepDescription {
+        data = typeof data === 'object' ? data : {};
+        let result = new SubpipelineStepDescription();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.steps && this.steps.constructor === Array) {
+            data["Steps"] = [];
+            for (let item of this.steps)
+                data["Steps"].push(item.toJSON());
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ISubpipelineStepDescription extends IStepDescription {
+    steps?: StepDescription[] | undefined;
+}
+
+export class PipelineDescription implements IPipelineDescription {
+    id?: string | undefined;
+    name?: string | undefined;
+    description?: string | undefined;
+    inputs?: PipelineDescriptionInput[] | undefined;
+    outputs?: PipelineDescriptionOutput[] | undefined;
+    steps?: PipelineDescriptionStep[] | undefined;
+
+    constructor(data?: IPipelineDescription) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.id = data["Id"];
+            this.name = data["Name"];
+            this.description = data["Description"];
+            if (data["Inputs"] && data["Inputs"].constructor === Array) {
+                this.inputs = [];
+                for (let item of data["Inputs"])
+                    this.inputs.push(PipelineDescriptionInput.fromJS(item));
+            }
+            if (data["Outputs"] && data["Outputs"].constructor === Array) {
+                this.outputs = [];
+                for (let item of data["Outputs"])
+                    this.outputs.push(PipelineDescriptionOutput.fromJS(item));
+            }
+            if (data["Steps"] && data["Steps"].constructor === Array) {
+                this.steps = [];
+                for (let item of data["Steps"])
+                    this.steps.push(PipelineDescriptionStep.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): PipelineDescription {
+        data = typeof data === 'object' ? data : {};
+        let result = new PipelineDescription();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Id"] = this.id;
+        data["Name"] = this.name;
+        data["Description"] = this.description;
+        if (this.inputs && this.inputs.constructor === Array) {
+            data["Inputs"] = [];
+            for (let item of this.inputs)
+                data["Inputs"].push(item.toJSON());
+        }
+        if (this.outputs && this.outputs.constructor === Array) {
+            data["Outputs"] = [];
+            for (let item of this.outputs)
+                data["Outputs"].push(item.toJSON());
+        }
+        if (this.steps && this.steps.constructor === Array) {
+            data["Steps"] = [];
+            for (let item of this.steps)
+                data["Steps"].push(item.toJSON());
+        }
+        return data;
+    }
+}
+
+export interface IPipelineDescription {
+    id?: string | undefined;
+    name?: string | undefined;
+    description?: string | undefined;
+    inputs?: PipelineDescriptionInput[] | undefined;
+    outputs?: PipelineDescriptionOutput[] | undefined;
+    steps?: PipelineDescriptionStep[] | undefined;
+}
+
+export class PipelineDescriptionInput implements IPipelineDescriptionInput {
+    name?: string | undefined;
+
+    constructor(data?: IPipelineDescriptionInput) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.name = data["Name"];
+        }
+    }
+
+    static fromJS(data: any): PipelineDescriptionInput {
+        data = typeof data === 'object' ? data : {};
+        let result = new PipelineDescriptionInput();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Name"] = this.name;
+        return data;
+    }
+}
+
+export interface IPipelineDescriptionInput {
+    name?: string | undefined;
+}
+
+export class PipelineDescriptionOutput implements IPipelineDescriptionOutput {
+    name?: string | undefined;
+    data?: string | undefined;
+
+    constructor(data?: IPipelineDescriptionOutput) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.name = data["Name"];
+            this.data = data["Data"];
+        }
+    }
+
+    static fromJS(data: any): PipelineDescriptionOutput {
+        data = typeof data === 'object' ? data : {};
+        let result = new PipelineDescriptionOutput();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Name"] = this.name;
+        data["Data"] = this.data;
+        return data;
+    }
+}
+
+export interface IPipelineDescriptionOutput {
+    name?: string | undefined;
+    data?: string | undefined;
+}
+
+export class PipelineDescriptionStep implements IPipelineDescriptionStep {
+    outputs?: StepOutput[] | undefined;
+
+    protected _discriminator: string;
+
+    constructor(data?: IPipelineDescriptionStep) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+        this._discriminator = "PipelineDescriptionStep";
+    }
+
+    init(data?: any) {
+        if (data) {
+            if (data["Outputs"] && data["Outputs"].constructor === Array) {
+                this.outputs = [];
+                for (let item of data["Outputs"])
+                    this.outputs.push(StepOutput.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): PipelineDescriptionStep {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "PlaceholderPipelineDescriptionStep") {
+            let result = new PlaceholderPipelineDescriptionStep();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "SubpipelinePipelineDescriptionStep") {
+            let result = new SubpipelinePipelineDescriptionStep();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "PrimitivePipelineDescriptionStep") {
+            let result = new PrimitivePipelineDescriptionStep();
+            result.init(data);
+            return result;
+        }
+        let result = new PipelineDescriptionStep();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        if (this.outputs && this.outputs.constructor === Array) {
+            data["Outputs"] = [];
+            for (let item of this.outputs)
+                data["Outputs"].push(item.toJSON());
+        }
+        return data;
+    }
+}
+
+export interface IPipelineDescriptionStep {
+    outputs?: StepOutput[] | undefined;
+}
+
+export class StepOutput implements IStepOutput {
+    id?: string | undefined;
+
+    constructor(data?: IStepOutput) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.id = data["Id"];
+        }
+    }
+
+    static fromJS(data: any): StepOutput {
+        data = typeof data === 'object' ? data : {};
+        let result = new StepOutput();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Id"] = this.id;
+        return data;
+    }
+}
+
+export interface IStepOutput {
+    id?: string | undefined;
+}
+
+export class PlaceholderPipelineDescriptionStep extends PipelineDescriptionStep implements IPlaceholderPipelineDescriptionStep {
+    inputs?: StepInput[] | undefined;
+
+    constructor(data?: IPlaceholderPipelineDescriptionStep) {
+        super(data);
+        this._discriminator = "PlaceholderPipelineDescriptionStep";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["Inputs"] && data["Inputs"].constructor === Array) {
+                this.inputs = [];
+                for (let item of data["Inputs"])
+                    this.inputs.push(StepInput.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): PlaceholderPipelineDescriptionStep {
+        data = typeof data === 'object' ? data : {};
+        let result = new PlaceholderPipelineDescriptionStep();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.inputs && this.inputs.constructor === Array) {
+            data["Inputs"] = [];
+            for (let item of this.inputs)
+                data["Inputs"].push(item.toJSON());
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IPlaceholderPipelineDescriptionStep extends IPipelineDescriptionStep {
+    inputs?: StepInput[] | undefined;
+}
+
+export class StepInput implements IStepInput {
+    data?: string | undefined;
+
+    constructor(data?: IStepInput) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.data = data["Data"];
+        }
+    }
+
+    static fromJS(data: any): StepInput {
+        data = typeof data === 'object' ? data : {};
+        let result = new StepInput();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Data"] = this.data;
+        return data;
+    }
+}
+
+export interface IStepInput {
+    data?: string | undefined;
+}
+
+export class SubpipelinePipelineDescriptionStep extends PipelineDescriptionStep implements ISubpipelinePipelineDescriptionStep {
+    pipelineDescription?: PipelineDescription | undefined;
+    inputs?: StepInput[] | undefined;
+
+    constructor(data?: ISubpipelinePipelineDescriptionStep) {
+        super(data);
+        this._discriminator = "SubpipelinePipelineDescriptionStep";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.pipelineDescription = data["PipelineDescription"] ? PipelineDescription.fromJS(data["PipelineDescription"]) : <any>undefined;
+            if (data["Inputs"] && data["Inputs"].constructor === Array) {
+                this.inputs = [];
+                for (let item of data["Inputs"])
+                    this.inputs.push(StepInput.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): SubpipelinePipelineDescriptionStep {
+        data = typeof data === 'object' ? data : {};
+        let result = new SubpipelinePipelineDescriptionStep();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["PipelineDescription"] = this.pipelineDescription ? this.pipelineDescription.toJSON() : <any>undefined;
+        if (this.inputs && this.inputs.constructor === Array) {
+            data["Inputs"] = [];
+            for (let item of this.inputs)
+                data["Inputs"].push(item.toJSON());
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ISubpipelinePipelineDescriptionStep extends IPipelineDescriptionStep {
+    pipelineDescription?: PipelineDescription | undefined;
+    inputs?: StepInput[] | undefined;
+}
+
+export class PrimitivePipelineDescriptionStep extends PipelineDescriptionStep implements IPrimitivePipelineDescriptionStep {
+    primitive?: Primitive | undefined;
+    arguments?: { [key: string]: PrimitiveStepArgument; } | undefined;
+    hyperparams?: { [key: string]: PrimitiveStepHyperparameter; } | undefined;
+
+    constructor(data?: IPrimitivePipelineDescriptionStep) {
+        super(data);
+        this._discriminator = "PrimitivePipelineDescriptionStep";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.primitive = data["Primitive"] ? Primitive.fromJS(data["Primitive"]) : <any>undefined;
+            if (data["Arguments"]) {
+                this.arguments = {};
+                for (let key in data["Arguments"]) {
+                    if (data["Arguments"].hasOwnProperty(key))
+                        this.arguments[key] = data["Arguments"][key] ? PrimitiveStepArgument.fromJS(data["Arguments"][key]) : new PrimitiveStepArgument();
+                }
+            }
+            if (data["Hyperparams"]) {
+                this.hyperparams = {};
+                for (let key in data["Hyperparams"]) {
+                    if (data["Hyperparams"].hasOwnProperty(key))
+                        this.hyperparams[key] = data["Hyperparams"][key] ? PrimitiveStepHyperparameter.fromJS(data["Hyperparams"][key]) : new PrimitiveStepHyperparameter();
+                }
+            }
+        }
+    }
+
+    static fromJS(data: any): PrimitivePipelineDescriptionStep {
+        data = typeof data === 'object' ? data : {};
+        let result = new PrimitivePipelineDescriptionStep();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Primitive"] = this.primitive ? this.primitive.toJSON() : <any>undefined;
+        if (this.arguments) {
+            data["Arguments"] = {};
+            for (let key in this.arguments) {
+                if (this.arguments.hasOwnProperty(key))
+                    data["Arguments"][key] = this.arguments[key];
+            }
+        }
+        if (this.hyperparams) {
+            data["Hyperparams"] = {};
+            for (let key in this.hyperparams) {
+                if (this.hyperparams.hasOwnProperty(key))
+                    data["Hyperparams"][key] = this.hyperparams[key];
+            }
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IPrimitivePipelineDescriptionStep extends IPipelineDescriptionStep {
+    primitive?: Primitive | undefined;
+    arguments?: { [key: string]: PrimitiveStepArgument; } | undefined;
+    hyperparams?: { [key: string]: PrimitiveStepHyperparameter; } | undefined;
+}
+
+export class Primitive implements IPrimitive {
+    id?: string | undefined;
+    version?: string | undefined;
+    pythonPath?: string | undefined;
+    name?: string | undefined;
+    digest?: string | undefined;
+
+    constructor(data?: IPrimitive) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.id = data["Id"];
+            this.version = data["Version"];
+            this.pythonPath = data["PythonPath"];
+            this.name = data["Name"];
+            this.digest = data["Digest"];
+        }
+    }
+
+    static fromJS(data: any): Primitive {
+        data = typeof data === 'object' ? data : {};
+        let result = new Primitive();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Id"] = this.id;
+        data["Version"] = this.version;
+        data["PythonPath"] = this.pythonPath;
+        data["Name"] = this.name;
+        data["Digest"] = this.digest;
+        return data;
+    }
+}
+
+export interface IPrimitive {
+    id?: string | undefined;
+    version?: string | undefined;
+    pythonPath?: string | undefined;
+    name?: string | undefined;
+    digest?: string | undefined;
+}
+
+export class PrimitiveStepHyperparameter implements IPrimitiveStepHyperparameter {
+
+    protected _discriminator: string;
+
+    constructor(data?: IPrimitiveStepHyperparameter) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+        this._discriminator = "PrimitiveStepHyperparameter";
+    }
+
+    init(data?: any) {
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): PrimitiveStepHyperparameter {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "PrimitiveStepArgument") {
+            let result = new PrimitiveStepArgument();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "DataArguments") {
+            let result = new DataArguments();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "PrimitiveArgument") {
+            let result = new PrimitiveArgument();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "PrimitiveArguments") {
+            let result = new PrimitiveArguments();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "ValueArgument") {
+            let result = new ValueArgument();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "ContainerArgument") {
+            let result = new ContainerArgument();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "DataArgument") {
+            let result = new DataArgument();
+            result.init(data);
+            return result;
+        }
+        let result = new PrimitiveStepHyperparameter();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        return data;
+    }
+}
+
+export interface IPrimitiveStepHyperparameter {
+}
+
+export class PrimitiveStepArgument extends PrimitiveStepHyperparameter implements IPrimitiveStepArgument {
+
+    protected _discriminator: string;
+
+    constructor(data?: IPrimitiveStepArgument) {
+        super(data);
+        this._discriminator = "PrimitiveStepArgument";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): PrimitiveStepArgument {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "ContainerArgument") {
+            let result = new ContainerArgument();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "DataArgument") {
+            let result = new DataArgument();
+            result.init(data);
+            return result;
+        }
+        let result = new PrimitiveStepArgument();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IPrimitiveStepArgument extends IPrimitiveStepHyperparameter {
+}
+
+export class DataArguments extends PrimitiveStepHyperparameter implements IDataArguments {
+    data?: string[] | undefined;
+
+    constructor(data?: IDataArguments) {
+        super(data);
+        this._discriminator = "DataArguments";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["Data"] && data["Data"].constructor === Array) {
+                this.data = [];
+                for (let item of data["Data"])
+                    this.data.push(item);
+            }
+        }
+    }
+
+    static fromJS(data: any): DataArguments {
+        data = typeof data === 'object' ? data : {};
+        let result = new DataArguments();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.data && this.data.constructor === Array) {
+            data["Data"] = [];
+            for (let item of this.data)
+                data["Data"].push(item);
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IDataArguments extends IPrimitiveStepHyperparameter {
+    data?: string[] | undefined;
+}
+
+export class PrimitiveArgument extends PrimitiveStepHyperparameter implements IPrimitiveArgument {
+    data?: number | undefined;
+
+    constructor(data?: IPrimitiveArgument) {
+        super(data);
+        this._discriminator = "PrimitiveArgument";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.data = data["Data"];
+        }
+    }
+
+    static fromJS(data: any): PrimitiveArgument {
+        data = typeof data === 'object' ? data : {};
+        let result = new PrimitiveArgument();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Data"] = this.data;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IPrimitiveArgument extends IPrimitiveStepHyperparameter {
+    data?: number | undefined;
+}
+
+export class PrimitiveArguments extends PrimitiveStepHyperparameter implements IPrimitiveArguments {
+    data?: number[] | undefined;
+
+    constructor(data?: IPrimitiveArguments) {
+        super(data);
+        this._discriminator = "PrimitiveArguments";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["Data"] && data["Data"].constructor === Array) {
+                this.data = [];
+                for (let item of data["Data"])
+                    this.data.push(item);
+            }
+        }
+    }
+
+    static fromJS(data: any): PrimitiveArguments {
+        data = typeof data === 'object' ? data : {};
+        let result = new PrimitiveArguments();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.data && this.data.constructor === Array) {
+            data["Data"] = [];
+            for (let item of this.data)
+                data["Data"].push(item);
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IPrimitiveArguments extends IPrimitiveStepHyperparameter {
+    data?: number[] | undefined;
+}
+
+export class ValueArgument extends PrimitiveStepHyperparameter implements IValueArgument {
+    data?: Value | undefined;
+
+    constructor(data?: IValueArgument) {
+        super(data);
+        this._discriminator = "ValueArgument";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.data = data["Data"] ? Value.fromJS(data["Data"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): ValueArgument {
+        data = typeof data === 'object' ? data : {};
+        let result = new ValueArgument();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Data"] = this.data ? this.data.toJSON() : <any>undefined;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IValueArgument extends IPrimitiveStepHyperparameter {
+    data?: Value | undefined;
+}
+
+export abstract class Value implements IValue {
+
+    protected _discriminator: string;
+
+    constructor(data?: IValue) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+        this._discriminator = "Value";
+    }
+
+    init(data?: any) {
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): Value {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "ErrorValue") {
+            let result = new ErrorValue();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "DoubleValue") {
+            let result = new DoubleValue();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "LongValue") {
+            let result = new LongValue();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "BoolValue") {
+            let result = new BoolValue();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "StringValue") {
+            let result = new StringValue();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "DatasetUriValue") {
+            let result = new DatasetUriValue();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "CsvUriValue") {
+            let result = new CsvUriValue();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "PickleUriValue") {
+            let result = new PickleUriValue();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "PickleBlobValue") {
+            let result = new PickleBlobValue();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "PlasmaIdValue") {
+            let result = new PlasmaIdValue();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "BytesValue") {
+            let result = new BytesValue();
+            result.init(data);
+            return result;
+        }
+        if (data["discriminator"] === "ListValue") {
+            let result = new ListValue();
+            result.init(data);
+            return result;
+        }
+        throw new Error("The abstract class 'Value' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        return data;
+    }
+}
+
+export interface IValue {
+}
+
+export class ErrorValue extends Value implements IErrorValue {
+    message?: string | undefined;
+
+    constructor(data?: IErrorValue) {
+        super(data);
+        this._discriminator = "ErrorValue";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.message = data["Message"];
+        }
+    }
+
+    static fromJS(data: any): ErrorValue {
+        data = typeof data === 'object' ? data : {};
+        let result = new ErrorValue();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Message"] = this.message;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IErrorValue extends IValue {
+    message?: string | undefined;
+}
+
+export class DoubleValue extends Value implements IDoubleValue {
+    value?: number | undefined;
+
+    constructor(data?: IDoubleValue) {
+        super(data);
+        this._discriminator = "DoubleValue";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): DoubleValue {
+        data = typeof data === 'object' ? data : {};
+        let result = new DoubleValue();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IDoubleValue extends IValue {
+    value?: number | undefined;
+}
+
+export class LongValue extends Value implements ILongValue {
+    value?: number | undefined;
+
+    constructor(data?: ILongValue) {
+        super(data);
+        this._discriminator = "LongValue";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): LongValue {
+        data = typeof data === 'object' ? data : {};
+        let result = new LongValue();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ILongValue extends IValue {
+    value?: number | undefined;
+}
+
+export class BoolValue extends Value implements IBoolValue {
+    value?: boolean | undefined;
+
+    constructor(data?: IBoolValue) {
+        super(data);
+        this._discriminator = "BoolValue";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): BoolValue {
+        data = typeof data === 'object' ? data : {};
+        let result = new BoolValue();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IBoolValue extends IValue {
+    value?: boolean | undefined;
+}
+
+export class StringValue extends Value implements IStringValue {
+    value?: string | undefined;
+
+    constructor(data?: IStringValue) {
+        super(data);
+        this._discriminator = "StringValue";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): StringValue {
+        data = typeof data === 'object' ? data : {};
+        let result = new StringValue();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IStringValue extends IValue {
+    value?: string | undefined;
+}
+
+export class DatasetUriValue extends Value implements IDatasetUriValue {
+    value?: string | undefined;
+
+    constructor(data?: IDatasetUriValue) {
+        super(data);
+        this._discriminator = "DatasetUriValue";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): DatasetUriValue {
+        data = typeof data === 'object' ? data : {};
+        let result = new DatasetUriValue();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IDatasetUriValue extends IValue {
+    value?: string | undefined;
+}
+
+export class CsvUriValue extends Value implements ICsvUriValue {
+    value?: string | undefined;
+
+    constructor(data?: ICsvUriValue) {
+        super(data);
+        this._discriminator = "CsvUriValue";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): CsvUriValue {
+        data = typeof data === 'object' ? data : {};
+        let result = new CsvUriValue();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ICsvUriValue extends IValue {
+    value?: string | undefined;
+}
+
+export class PickleUriValue extends Value implements IPickleUriValue {
+    value?: string | undefined;
+
+    constructor(data?: IPickleUriValue) {
+        super(data);
+        this._discriminator = "PickleUriValue";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): PickleUriValue {
+        data = typeof data === 'object' ? data : {};
+        let result = new PickleUriValue();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IPickleUriValue extends IValue {
+    value?: string | undefined;
+}
+
+export class PickleBlobValue extends Value implements IPickleBlobValue {
+    value?: string | undefined;
+
+    constructor(data?: IPickleBlobValue) {
+        super(data);
+        this._discriminator = "PickleBlobValue";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): PickleBlobValue {
+        data = typeof data === 'object' ? data : {};
+        let result = new PickleBlobValue();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IPickleBlobValue extends IValue {
+    value?: string | undefined;
+}
+
+export class PlasmaIdValue extends Value implements IPlasmaIdValue {
+    value?: string | undefined;
+
+    constructor(data?: IPlasmaIdValue) {
+        super(data);
+        this._discriminator = "PlasmaIdValue";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): PlasmaIdValue {
+        data = typeof data === 'object' ? data : {};
+        let result = new PlasmaIdValue();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IPlasmaIdValue extends IValue {
+    value?: string | undefined;
+}
+
+export class BytesValue extends Value implements IBytesValue {
+    value?: string | undefined;
+
+    constructor(data?: IBytesValue) {
+        super(data);
+        this._discriminator = "BytesValue";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): BytesValue {
+        data = typeof data === 'object' ? data : {};
+        let result = new BytesValue();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IBytesValue extends IValue {
+    value?: string | undefined;
+}
+
+export class ContainerArgument extends PrimitiveStepArgument implements IContainerArgument {
+    data?: string | undefined;
+
+    constructor(data?: IContainerArgument) {
+        super(data);
+        this._discriminator = "ContainerArgument";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.data = data["Data"];
+        }
+    }
+
+    static fromJS(data: any): ContainerArgument {
+        data = typeof data === 'object' ? data : {};
+        let result = new ContainerArgument();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Data"] = this.data;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IContainerArgument extends IPrimitiveStepArgument {
+    data?: string | undefined;
+}
+
+export class Score implements IScore {
+    metricType?: MetricType | undefined;
+    value?: number | undefined;
+
+    constructor(data?: IScore) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.metricType = data["MetricType"];
+            this.value = data["Value"];
+        }
+    }
+
+    static fromJS(data: any): Score {
+        data = typeof data === 'object' ? data : {};
+        let result = new Score();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["MetricType"] = this.metricType;
+        data["Value"] = this.value;
+        return data;
+    }
+}
+
+export interface IScore {
+    metricType?: MetricType | undefined;
+    value?: number | undefined;
+}
+
+export class ExampleResult extends Result implements IExampleResult {
+    resultValues?: { [key: string]: string; } | undefined;
+    message?: string | undefined;
+
+    constructor(data?: IExampleResult) {
+        super(data);
+        this._discriminator = "ExampleResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["ResultValues"]) {
+                this.resultValues = {};
+                for (let key in data["ResultValues"]) {
+                    if (data["ResultValues"].hasOwnProperty(key))
+                        this.resultValues[key] = data["ResultValues"][key];
+                }
+            }
+            this.message = data["Message"];
+        }
+    }
+
+    static fromJS(data: any): ExampleResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new ExampleResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.resultValues) {
+            data["ResultValues"] = {};
+            for (let key in this.resultValues) {
+                if (this.resultValues.hasOwnProperty(key))
+                    data["ResultValues"][key] = this.resultValues[key];
+            }
+        }
+        data["Message"] = this.message;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IExampleResult extends IResult {
+    resultValues?: { [key: string]: string; } | undefined;
+    message?: string | undefined;
+}
+
+export class NewModelOperationResult extends ModelOperationResult implements INewModelOperationResult {
+
+    constructor(data?: INewModelOperationResult) {
+        super(data);
+        this._discriminator = "NewModelOperationResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): NewModelOperationResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new NewModelOperationResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface INewModelOperationResult extends IModelOperationResult {
+}
+
+export class AddComparisonResult extends ModelOperationResult implements IAddComparisonResult {
+    comparisonId?: ComparisonId | undefined;
+
+    constructor(data?: IAddComparisonResult) {
+        super(data);
+        this._discriminator = "AddComparisonResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.comparisonId = data["ComparisonId"] ? ComparisonId.fromJS(data["ComparisonId"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): AddComparisonResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new AddComparisonResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["ComparisonId"] = this.comparisonId ? this.comparisonId.toJSON() : <any>undefined;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IAddComparisonResult extends IModelOperationResult {
+    comparisonId?: ComparisonId | undefined;
+}
+
+export class GetModelStateResult extends ModelOperationResult implements IGetModelStateResult {
+    decisions?: Decision[] | undefined;
+    startingWealth?: number | undefined;
+    currentWealth?: number | undefined;
+
+    constructor(data?: IGetModelStateResult) {
+        super(data);
+        this._discriminator = "GetModelStateResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["Decisions"] && data["Decisions"].constructor === Array) {
+                this.decisions = [];
+                for (let item of data["Decisions"])
+                    this.decisions.push(Decision.fromJS(item));
+            }
+            this.startingWealth = data["StartingWealth"];
+            this.currentWealth = data["CurrentWealth"];
+        }
+    }
+
+    static fromJS(data: any): GetModelStateResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new GetModelStateResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.decisions && this.decisions.constructor === Array) {
+            data["Decisions"] = [];
+            for (let item of this.decisions)
+                data["Decisions"].push(item.toJSON());
+        }
+        data["StartingWealth"] = this.startingWealth;
+        data["CurrentWealth"] = this.currentWealth;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IGetModelStateResult extends IModelOperationResult {
+    decisions?: Decision[] | undefined;
+    startingWealth?: number | undefined;
+    currentWealth?: number | undefined;
+}
+
+export class AggregateKey implements IAggregateKey {
+    aggregateParameterIndex?: number | undefined;
+    brushIndex?: number | undefined;
+
+    constructor(data?: IAggregateKey) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.aggregateParameterIndex = data["AggregateParameterIndex"];
+            this.brushIndex = data["BrushIndex"];
+        }
+    }
+
+    static fromJS(data: any): AggregateKey {
+        data = typeof data === 'object' ? data : {};
+        let result = new AggregateKey();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["AggregateParameterIndex"] = this.aggregateParameterIndex;
+        data["BrushIndex"] = this.brushIndex;
+        return data;
+    }
+}
+
+export interface IAggregateKey {
+    aggregateParameterIndex?: number | undefined;
+    brushIndex?: number | undefined;
+}
+
+export abstract class IResult implements IIResult {
+
+    constructor(data?: IIResult) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): IResult {
+        data = typeof data === 'object' ? data : {};
+        throw new Error("The abstract class 'IResult' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        return data;
+    }
+}
+
+export interface IIResult {
+}
+
+export class DataArgument extends PrimitiveStepArgument implements IDataArgument {
+    data?: string | undefined;
+
+    constructor(data?: IDataArgument) {
+        super(data);
+        this._discriminator = "DataArgument";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.data = data["Data"];
+        }
+    }
+
+    static fromJS(data: any): DataArgument {
+        data = typeof data === 'object' ? data : {};
+        let result = new DataArgument();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Data"] = this.data;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IDataArgument extends IPrimitiveStepArgument {
+    data?: string | undefined;
+}
+
+export class ListValue extends Value implements IListValue {
+    items?: Value[] | undefined;
+
+    constructor(data?: IListValue) {
+        super(data);
+        this._discriminator = "ListValue";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["Items"] && data["Items"].constructor === Array) {
+                this.items = [];
+                for (let item of data["Items"])
+                    this.items.push(Value.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): ListValue {
+        data = typeof data === 'object' ? data : {};
+        let result = new ListValue();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.items && this.items.constructor === Array) {
+            data["Items"] = [];
+            for (let item of this.items)
+                data["Items"].push(item.toJSON());
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IListValue extends IValue {
+    items?: Value[] | undefined;
+}
+
+export class Metrics implements IMetrics {
+    averageAccuracy?: number | undefined;
+    averageRSquared?: number | undefined;
+    f1Macro?: number | undefined;
+
+    constructor(data?: IMetrics) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.averageAccuracy = data["AverageAccuracy"];
+            this.averageRSquared = data["AverageRSquared"];
+            this.f1Macro = data["F1Macro"];
+        }
+    }
+
+    static fromJS(data: any): Metrics {
+        data = typeof data === 'object' ? data : {};
+        let result = new Metrics();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["AverageAccuracy"] = this.averageAccuracy;
+        data["AverageRSquared"] = this.averageRSquared;
+        data["F1Macro"] = this.f1Macro;
+        return data;
+    }
+}
+
+export interface IMetrics {
+    averageAccuracy?: number | undefined;
+    averageRSquared?: number | undefined;
+    f1Macro?: number | undefined;
+}
+
+export class FeatureImportanceOperationParameters extends DistOperationParameters implements IFeatureImportanceOperationParameters {
+    solutionId?: string | undefined;
+
+    constructor(data?: IFeatureImportanceOperationParameters) {
+        super(data);
+        this._discriminator = "FeatureImportanceOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.solutionId = data["SolutionId"];
+        }
+    }
+
+    static fromJS(data: any): FeatureImportanceOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new FeatureImportanceOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["SolutionId"] = this.solutionId;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IFeatureImportanceOperationParameters extends IDistOperationParameters {
+    solutionId?: string | undefined;
+}
+
+export class FeatureImportanceResult extends Result implements IFeatureImportanceResult {
+    featureImportances?: { [key: string]: TupleOfDoubleAndDouble; } | undefined;
+
+    constructor(data?: IFeatureImportanceResult) {
+        super(data);
+        this._discriminator = "FeatureImportanceResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["FeatureImportances"]) {
+                this.featureImportances = {};
+                for (let key in data["FeatureImportances"]) {
+                    if (data["FeatureImportances"].hasOwnProperty(key))
+                        this.featureImportances[key] = data["FeatureImportances"][key] ? TupleOfDoubleAndDouble.fromJS(data["FeatureImportances"][key]) : new TupleOfDoubleAndDouble();
+                }
+            }
+        }
+    }
+
+    static fromJS(data: any): FeatureImportanceResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new FeatureImportanceResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.featureImportances) {
+            data["FeatureImportances"] = {};
+            for (let key in this.featureImportances) {
+                if (this.featureImportances.hasOwnProperty(key))
+                    data["FeatureImportances"][key] = this.featureImportances[key];
+            }
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IFeatureImportanceResult extends IResult {
+    featureImportances?: { [key: string]: TupleOfDoubleAndDouble; } | undefined;
+}
+
+export class TupleOfDoubleAndDouble implements ITupleOfDoubleAndDouble {
+    item1?: number | undefined;
+    item2?: number | undefined;
+
+    constructor(data?: ITupleOfDoubleAndDouble) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.item1 = data["Item1"];
+            this.item2 = data["Item2"];
+        }
+    }
+
+    static fromJS(data: any): TupleOfDoubleAndDouble {
+        data = typeof data === 'object' ? data : {};
+        let result = new TupleOfDoubleAndDouble();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Item1"] = this.item1;
+        data["Item2"] = this.item2;
+        return data;
+    }
+}
+
+export interface ITupleOfDoubleAndDouble {
+    item1?: number | undefined;
+    item2?: number | undefined;
+}
+
+export class PrimitiveStepDescription extends StepDescription implements IPrimitiveStepDescription {
+    hyperparams?: { [key: string]: Value; } | undefined;
+
+    constructor(data?: IPrimitiveStepDescription) {
+        super(data);
+        this._discriminator = "PrimitiveStepDescription";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["Hyperparams"]) {
+                this.hyperparams = {};
+                for (let key in data["Hyperparams"]) {
+                    if (data["Hyperparams"].hasOwnProperty(key))
+                        this.hyperparams[key] = data["Hyperparams"][key] ? Value.fromJS(data["Hyperparams"][key]) : <any>undefined;
+                }
+            }
+        }
+    }
+
+    static fromJS(data: any): PrimitiveStepDescription {
+        data = typeof data === 'object' ? data : {};
+        let result = new PrimitiveStepDescription();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.hyperparams) {
+            data["Hyperparams"] = {};
+            for (let key in this.hyperparams) {
+                if (this.hyperparams.hasOwnProperty(key))
+                    data["Hyperparams"][key] = this.hyperparams[key];
+            }
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IPrimitiveStepDescription extends IStepDescription {
+    hyperparams?: { [key: string]: Value; } | undefined;
+}
+
+export enum ValueType {
+    VALUE_TYPE_UNDEFINED = 0,
+    RAW = 1,
+    DATASET_URI = 2,
+    CSV_URI = 3,
+    PICKLE_URI = 4,
+    PICKLE_BLOB = 5,
+    PLASMA_ID = 6,
+}
+
+export class DatamartSearchParameters implements IDatamartSearchParameters {
+    adapterName?: string | undefined;
+    queryJson?: string | undefined;
+
+    constructor(data?: IDatamartSearchParameters) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.adapterName = data["AdapterName"];
+            this.queryJson = data["QueryJson"];
+        }
+    }
+
+    static fromJS(data: any): DatamartSearchParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new DatamartSearchParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["AdapterName"] = this.adapterName;
+        data["QueryJson"] = this.queryJson;
+        return data;
+    }
+}
+
+export interface IDatamartSearchParameters {
+    adapterName?: string | undefined;
+    queryJson?: string | undefined;
+}
+
+export class DatamartAugmentParameters implements IDatamartAugmentParameters {
+    adapterName?: string | undefined;
+    augmentationJson?: string | undefined;
+    numberOfSamples?: number | undefined;
+    augmentedAdapterName?: string | undefined;
+
+    constructor(data?: IDatamartAugmentParameters) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.adapterName = data["AdapterName"];
+            this.augmentationJson = data["AugmentationJson"];
+            this.numberOfSamples = data["NumberOfSamples"];
+            this.augmentedAdapterName = data["AugmentedAdapterName"];
+        }
+    }
+
+    static fromJS(data: any): DatamartAugmentParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new DatamartAugmentParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["AdapterName"] = this.adapterName;
+        data["AugmentationJson"] = this.augmentationJson;
+        data["NumberOfSamples"] = this.numberOfSamples;
+        data["AugmentedAdapterName"] = this.augmentedAdapterName;
+        return data;
+    }
+}
+
+export interface IDatamartAugmentParameters {
+    adapterName?: string | undefined;
+    augmentationJson?: string | undefined;
+    numberOfSamples?: number | undefined;
+    augmentedAdapterName?: string | undefined;
+}
+
+export class RawDataResult extends DistResult implements IRawDataResult {
+    samples?: { [key: string]: any[]; } | undefined;
+    weightedWords?: { [key: string]: Word[]; } | undefined;
+
+    constructor(data?: IRawDataResult) {
+        super(data);
+        this._discriminator = "RawDataResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["Samples"]) {
+                this.samples = {};
+                for (let key in data["Samples"]) {
+                    if (data["Samples"].hasOwnProperty(key))
+                        this.samples[key] = data["Samples"][key] !== undefined ? data["Samples"][key] : [];
+                }
+            }
+            if (data["WeightedWords"]) {
+                this.weightedWords = {};
+                for (let key in data["WeightedWords"]) {
+                    if (data["WeightedWords"].hasOwnProperty(key))
+                        this.weightedWords[key] = data["WeightedWords"][key] ? data["WeightedWords"][key].map((i: any) => Word.fromJS(i)) : [];
+                }
+            }
+        }
+    }
+
+    static fromJS(data: any): RawDataResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new RawDataResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.samples) {
+            data["Samples"] = {};
+            for (let key in this.samples) {
+                if (this.samples.hasOwnProperty(key))
+                    data["Samples"][key] = this.samples[key];
+            }
+        }
+        if (this.weightedWords) {
+            data["WeightedWords"] = {};
+            for (let key in this.weightedWords) {
+                if (this.weightedWords.hasOwnProperty(key))
+                    data["WeightedWords"][key] = this.weightedWords[key];
+            }
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IRawDataResult extends IDistResult {
+    samples?: { [key: string]: any[]; } | undefined;
+    weightedWords?: { [key: string]: Word[]; } | undefined;
+}
+
+export class Word implements IWord {
+    text?: string | undefined;
+    occurrences?: number | undefined;
+    stem?: string | undefined;
+    isWordGroup?: boolean | undefined;
+
+    constructor(data?: IWord) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.text = data["Text"];
+            this.occurrences = data["Occurrences"];
+            this.stem = data["Stem"];
+            this.isWordGroup = data["IsWordGroup"];
+        }
+    }
+
+    static fromJS(data: any): Word {
+        data = typeof data === 'object' ? data : {};
+        let result = new Word();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Text"] = this.text;
+        data["Occurrences"] = this.occurrences;
+        data["Stem"] = this.stem;
+        data["IsWordGroup"] = this.isWordGroup;
+        return data;
+    }
+}
+
+export interface IWord {
+    text?: string | undefined;
+    occurrences?: number | undefined;
+    stem?: string | undefined;
+    isWordGroup?: boolean | undefined;
+}
+
+export class SampleOperationParameters extends DistOperationParameters implements ISampleOperationParameters {
+    numSamples?: number | undefined;
+    attributeParameters?: AttributeParameters[] | undefined;
+    brushes?: string[] | undefined;
+
+    constructor(data?: ISampleOperationParameters) {
+        super(data);
+        this._discriminator = "SampleOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.numSamples = data["NumSamples"];
+            if (data["AttributeParameters"] && data["AttributeParameters"].constructor === Array) {
+                this.attributeParameters = [];
+                for (let item of data["AttributeParameters"])
+                    this.attributeParameters.push(AttributeParameters.fromJS(item));
+            }
+            if (data["Brushes"] && data["Brushes"].constructor === Array) {
+                this.brushes = [];
+                for (let item of data["Brushes"])
+                    this.brushes.push(item);
+            }
+        }
+    }
+
+    static fromJS(data: any): SampleOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new SampleOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["NumSamples"] = this.numSamples;
+        if (this.attributeParameters && this.attributeParameters.constructor === Array) {
+            data["AttributeParameters"] = [];
+            for (let item of this.attributeParameters)
+                data["AttributeParameters"].push(item.toJSON());
+        }
+        if (this.brushes && this.brushes.constructor === Array) {
+            data["Brushes"] = [];
+            for (let item of this.brushes)
+                data["Brushes"].push(item);
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ISampleOperationParameters extends IDistOperationParameters {
+    numSamples?: number | undefined;
+    attributeParameters?: AttributeParameters[] | undefined;
+    brushes?: string[] | undefined;
+}
+
+export class SampleResult extends DistResult implements ISampleResult {
+    samples?: { [key: string]: { [key: string]: number; }; } | undefined;
+    isTruncated?: boolean | undefined;
+
+    constructor(data?: ISampleResult) {
+        super(data);
+        this._discriminator = "SampleResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["Samples"]) {
+                this.samples = {};
+                for (let key in data["Samples"]) {
+                    if (data["Samples"].hasOwnProperty(key))
+                        this.samples[key] = data["Samples"][key] !== undefined ? data["Samples"][key] : {};
+                }
+            }
+            this.isTruncated = data["IsTruncated"];
+        }
+    }
+
+    static fromJS(data: any): SampleResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new SampleResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.samples) {
+            data["Samples"] = {};
+            for (let key in this.samples) {
+                if (this.samples.hasOwnProperty(key))
+                    data["Samples"][key] = this.samples[key];
+            }
+        }
+        data["IsTruncated"] = this.isTruncated;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ISampleResult extends IDistResult {
+    samples?: { [key: string]: { [key: string]: number; }; } | undefined;
+    isTruncated?: boolean | undefined;
+}
+
+export class ResultParameters extends UniqueJson implements IResultParameters {
+    operationReference?: IOperationReference | undefined;
+    stopOperation?: boolean | undefined;
+
+    protected _discriminator: string;
+
+    constructor(data?: IResultParameters) {
+        super(data);
+        this._discriminator = "ResultParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.operationReference = data["OperationReference"] ? IOperationReference.fromJS(data["OperationReference"]) : <any>undefined;
+            this.stopOperation = data["StopOperation"];
+        }
+    }
+
+    static fromJS(data: any): ResultParameters {
+        data = typeof data === 'object' ? data : {};
+        if (data["discriminator"] === "RecommenderResultParameters") {
+            let result = new RecommenderResultParameters();
+            result.init(data);
+            return result;
+        }
+        let result = new ResultParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["discriminator"] = this._discriminator;
+        data["OperationReference"] = this.operationReference ? this.operationReference.toJSON() : <any>undefined;
+        data["StopOperation"] = this.stopOperation;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IResultParameters extends IUniqueJson {
+    operationReference?: IOperationReference | undefined;
+    stopOperation?: boolean | undefined;
+}
+
+export class RecommenderResultParameters extends ResultParameters implements IRecommenderResultParameters {
+    from?: number | undefined;
+    to?: number | undefined;
+    pValueSorting?: Sorting | undefined;
+    effectSizeFilter?: EffectSize | undefined;
+
+    constructor(data?: IRecommenderResultParameters) {
+        super(data);
+        this._discriminator = "RecommenderResultParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.from = data["From"];
+            this.to = data["To"];
+            this.pValueSorting = data["PValueSorting"];
+            this.effectSizeFilter = data["EffectSizeFilter"];
+        }
+    }
+
+    static fromJS(data: any): RecommenderResultParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new RecommenderResultParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["From"] = this.from;
+        data["To"] = this.to;
+        data["PValueSorting"] = this.pValueSorting;
+        data["EffectSizeFilter"] = this.effectSizeFilter;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IRecommenderResultParameters extends IResultParameters {
+    from?: number | undefined;
+    to?: number | undefined;
+    pValueSorting?: Sorting | undefined;
+    effectSizeFilter?: EffectSize | undefined;
+}
+
+export enum Sorting {
+    Ascending = "Ascending",
+    Descending = "Descending",
+}
+
+export class AddComparisonParameters extends ModelOperationParameters implements IAddComparisonParameters {
+    modelId?: ModelId | undefined;
+    comparisonOrder?: number | undefined;
+    childOperationParameters?: OperationParameters[] | undefined;
+    isCachable?: boolean | undefined;
+
+    constructor(data?: IAddComparisonParameters) {
+        super(data);
+        this._discriminator = "AddComparisonParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.modelId = data["ModelId"] ? ModelId.fromJS(data["ModelId"]) : <any>undefined;
+            this.comparisonOrder = data["ComparisonOrder"];
+            if (data["ChildOperationParameters"] && data["ChildOperationParameters"].constructor === Array) {
+                this.childOperationParameters = [];
+                for (let item of data["ChildOperationParameters"])
+                    this.childOperationParameters.push(OperationParameters.fromJS(item));
+            }
+            this.isCachable = data["IsCachable"];
+        }
+    }
+
+    static fromJS(data: any): AddComparisonParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new AddComparisonParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["ModelId"] = this.modelId ? this.modelId.toJSON() : <any>undefined;
+        data["ComparisonOrder"] = this.comparisonOrder;
+        if (this.childOperationParameters && this.childOperationParameters.constructor === Array) {
+            data["ChildOperationParameters"] = [];
+            for (let item of this.childOperationParameters)
+                data["ChildOperationParameters"].push(item.toJSON());
+        }
+        data["IsCachable"] = this.isCachable;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IAddComparisonParameters extends IModelOperationParameters {
+    modelId?: ModelId | undefined;
+    comparisonOrder?: number | undefined;
+    childOperationParameters?: OperationParameters[] | undefined;
+    isCachable?: boolean | undefined;
+}
+
+export class CDFResult extends DistResult implements ICDFResult {
+    cDF?: { [key: string]: number; } | undefined;
+
+    constructor(data?: ICDFResult) {
+        super(data);
+        this._discriminator = "CDFResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["CDF"]) {
+                this.cDF = {};
+                for (let key in data["CDF"]) {
+                    if (data["CDF"].hasOwnProperty(key))
+                        this.cDF[key] = data["CDF"][key];
+                }
+            }
+        }
+    }
+
+    static fromJS(data: any): CDFResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new CDFResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.cDF) {
+            data["CDF"] = {};
+            for (let key in this.cDF) {
+                if (this.cDF.hasOwnProperty(key))
+                    data["CDF"][key] = this.cDF[key];
+            }
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ICDFResult extends IDistResult {
+    cDF?: { [key: string]: number; } | undefined;
+}
+
+export class ChiSquaredTestResult extends HypothesisTestResult implements IChiSquaredTestResult {
+    hs_aligned?: TupleOfDoubleAndDouble[] | undefined;
+
+    constructor(data?: IChiSquaredTestResult) {
+        super(data);
+        this._discriminator = "ChiSquaredTestResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["hs_aligned"] && data["hs_aligned"].constructor === Array) {
+                this.hs_aligned = [];
+                for (let item of data["hs_aligned"])
+                    this.hs_aligned.push(TupleOfDoubleAndDouble.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): ChiSquaredTestResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new ChiSquaredTestResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.hs_aligned && this.hs_aligned.constructor === Array) {
+            data["hs_aligned"] = [];
+            for (let item of this.hs_aligned)
+                data["hs_aligned"].push(item.toJSON());
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IChiSquaredTestResult extends IHypothesisTestResult {
+    hs_aligned?: TupleOfDoubleAndDouble[] | undefined;
+}
+
+export class CorrelationTestResult extends HypothesisTestResult implements ICorrelationTestResult {
+    degreeOfFreedom?: number | undefined;
+    sampleCorrelationCoefficient?: number | undefined;
+    distResult?: EmpiricalDistResult | undefined;
+
+    constructor(data?: ICorrelationTestResult) {
+        super(data);
+        this._discriminator = "CorrelationTestResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.degreeOfFreedom = data["DegreeOfFreedom"];
+            this.sampleCorrelationCoefficient = data["SampleCorrelationCoefficient"];
+            this.distResult = data["DistResult"] ? EmpiricalDistResult.fromJS(data["DistResult"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): CorrelationTestResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new CorrelationTestResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["DegreeOfFreedom"] = this.degreeOfFreedom;
+        data["SampleCorrelationCoefficient"] = this.sampleCorrelationCoefficient;
+        data["DistResult"] = this.distResult ? this.distResult.toJSON() : <any>undefined;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ICorrelationTestResult extends IHypothesisTestResult {
+    degreeOfFreedom?: number | undefined;
+    sampleCorrelationCoefficient?: number | undefined;
+    distResult?: EmpiricalDistResult | undefined;
+}
+
+export class EmpiricalDistResult extends DistResult implements IEmpiricalDistResult {
+    marginals?: AttributeParameters[] | undefined;
+    marginalDistParameters?: { [key: string]: DistParameter; } | undefined;
+    jointDistParameter?: JointDistParameter | undefined;
+
+    constructor(data?: IEmpiricalDistResult) {
+        super(data);
+        this._discriminator = "EmpiricalDistResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["Marginals"] && data["Marginals"].constructor === Array) {
+                this.marginals = [];
+                for (let item of data["Marginals"])
+                    this.marginals.push(AttributeParameters.fromJS(item));
+            }
+            if (data["MarginalDistParameters"]) {
+                this.marginalDistParameters = {};
+                for (let key in data["MarginalDistParameters"]) {
+                    if (data["MarginalDistParameters"].hasOwnProperty(key))
+                        this.marginalDistParameters[key] = data["MarginalDistParameters"][key] ? DistParameter.fromJS(data["MarginalDistParameters"][key]) : new DistParameter();
+                }
+            }
+            this.jointDistParameter = data["JointDistParameter"] ? JointDistParameter.fromJS(data["JointDistParameter"]) : <any>undefined;
+        }
+    }
+
+    static fromJS(data: any): EmpiricalDistResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new EmpiricalDistResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.marginals && this.marginals.constructor === Array) {
+            data["Marginals"] = [];
+            for (let item of this.marginals)
+                data["Marginals"].push(item.toJSON());
+        }
+        if (this.marginalDistParameters) {
+            data["MarginalDistParameters"] = {};
+            for (let key in this.marginalDistParameters) {
+                if (this.marginalDistParameters.hasOwnProperty(key))
+                    data["MarginalDistParameters"][key] = this.marginalDistParameters[key];
+            }
+        }
+        data["JointDistParameter"] = this.jointDistParameter ? this.jointDistParameter.toJSON() : <any>undefined;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IEmpiricalDistResult extends IDistResult {
+    marginals?: AttributeParameters[] | undefined;
+    marginalDistParameters?: { [key: string]: DistParameter; } | undefined;
+    jointDistParameter?: JointDistParameter | undefined;
+}
+
+export class DistParameter implements IDistParameter {
+    mean?: number | undefined;
+    moment2?: number | undefined;
+    variance?: number | undefined;
+    varianceEstimate?: number | undefined;
+    min?: number | undefined;
+    max?: number | undefined;
+
+    constructor(data?: IDistParameter) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.mean = data["Mean"];
+            this.moment2 = data["Moment2"];
+            this.variance = data["Variance"];
+            this.varianceEstimate = data["VarianceEstimate"];
+            this.min = data["Min"];
+            this.max = data["Max"];
+        }
+    }
+
+    static fromJS(data: any): DistParameter {
+        data = typeof data === 'object' ? data : {};
+        let result = new DistParameter();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Mean"] = this.mean;
+        data["Moment2"] = this.moment2;
+        data["Variance"] = this.variance;
+        data["VarianceEstimate"] = this.varianceEstimate;
+        data["Min"] = this.min;
+        data["Max"] = this.max;
+        return data;
+    }
+}
+
+export interface IDistParameter {
+    mean?: number | undefined;
+    moment2?: number | undefined;
+    variance?: number | undefined;
+    varianceEstimate?: number | undefined;
+    min?: number | undefined;
+    max?: number | undefined;
+}
+
+export class JointDistParameter implements IJointDistParameter {
+    jointDist?: DistParameter | undefined;
+    covariance?: number | undefined;
+
+    constructor(data?: IJointDistParameter) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.jointDist = data["JointDist"] ? DistParameter.fromJS(data["JointDist"]) : <any>undefined;
+            this.covariance = data["Covariance"];
+        }
+    }
+
+    static fromJS(data: any): JointDistParameter {
+        data = typeof data === 'object' ? data : {};
+        let result = new JointDistParameter();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["JointDist"] = this.jointDist ? this.jointDist.toJSON() : <any>undefined;
+        data["Covariance"] = this.covariance;
+        return data;
+    }
+}
+
+export interface IJointDistParameter {
+    jointDist?: DistParameter | undefined;
+    covariance?: number | undefined;
+}
+
+export enum DistributionType {
+    Continuous = 0,
+    Discrete = 1,
+}
+
+export abstract class DistributionTypeExtension implements IDistributionTypeExtension {
+
+    constructor(data?: IDistributionTypeExtension) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): DistributionTypeExtension {
+        data = typeof data === 'object' ? data : {};
+        throw new Error("The abstract class 'DistributionTypeExtension' cannot be instantiated.");
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        return data;
+    }
+}
+
+export interface IDistributionTypeExtension {
+}
+
+export class GetModelStateParameters extends ModelOperationParameters implements IGetModelStateParameters {
+    modelId?: ModelId | undefined;
+    comparisonIds?: ComparisonId[] | undefined;
+    riskControlType?: RiskControlType | undefined;
+
+    constructor(data?: IGetModelStateParameters) {
+        super(data);
+        this._discriminator = "GetModelStateParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.modelId = data["ModelId"] ? ModelId.fromJS(data["ModelId"]) : <any>undefined;
+            if (data["ComparisonIds"] && data["ComparisonIds"].constructor === Array) {
+                this.comparisonIds = [];
+                for (let item of data["ComparisonIds"])
+                    this.comparisonIds.push(ComparisonId.fromJS(item));
+            }
+            this.riskControlType = data["RiskControlType"];
+        }
+    }
+
+    static fromJS(data: any): GetModelStateParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new GetModelStateParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["ModelId"] = this.modelId ? this.modelId.toJSON() : <any>undefined;
+        if (this.comparisonIds && this.comparisonIds.constructor === Array) {
+            data["ComparisonIds"] = [];
+            for (let item of this.comparisonIds)
+                data["ComparisonIds"].push(item.toJSON());
+        }
+        data["RiskControlType"] = this.riskControlType;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IGetModelStateParameters extends IModelOperationParameters {
+    modelId?: ModelId | undefined;
+    comparisonIds?: ComparisonId[] | undefined;
+    riskControlType?: RiskControlType | undefined;
+}
+
+export class KSTestResult extends HypothesisTestResult implements IKSTestResult {
+
+    constructor(data?: IKSTestResult) {
+        super(data);
+        this._discriminator = "KSTestResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): KSTestResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new KSTestResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IKSTestResult extends IHypothesisTestResult {
+}
+
+export class ModelWealthParameters extends UniqueJson implements IModelWealthParameters {
+    modelId?: ModelId | undefined;
+    riskControlType?: RiskControlType | undefined;
+
+    constructor(data?: IModelWealthParameters) {
+        super(data);
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.modelId = data["ModelId"] ? ModelId.fromJS(data["ModelId"]) : <any>undefined;
+            this.riskControlType = data["RiskControlType"];
+        }
+    }
+
+    static fromJS(data: any): ModelWealthParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new ModelWealthParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["ModelId"] = this.modelId ? this.modelId.toJSON() : <any>undefined;
+        data["RiskControlType"] = this.riskControlType;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IModelWealthParameters extends IUniqueJson {
+    modelId?: ModelId | undefined;
+    riskControlType?: RiskControlType | undefined;
+}
+
+export class RootMeanSquareTestResult extends HypothesisTestResult implements IRootMeanSquareTestResult {
+    simulationCount?: number | undefined;
+    extremeSimulationCount?: number | undefined;
+
+    constructor(data?: IRootMeanSquareTestResult) {
+        super(data);
+        this._discriminator = "RootMeanSquareTestResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.simulationCount = data["SimulationCount"];
+            this.extremeSimulationCount = data["ExtremeSimulationCount"];
+        }
+    }
+
+    static fromJS(data: any): RootMeanSquareTestResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new RootMeanSquareTestResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["SimulationCount"] = this.simulationCount;
+        data["ExtremeSimulationCount"] = this.extremeSimulationCount;
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IRootMeanSquareTestResult extends IHypothesisTestResult {
+    simulationCount?: number | undefined;
+    extremeSimulationCount?: number | undefined;
+}
+
+export class TTestResult extends HypothesisTestResult implements ITTestResult {
+    degreeOfFreedom?: number | undefined;
+    distResults?: EmpiricalDistResult[] | undefined;
+
+    constructor(data?: ITTestResult) {
+        super(data);
+        this._discriminator = "TTestResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.degreeOfFreedom = data["DegreeOfFreedom"];
+            if (data["DistResults"] && data["DistResults"].constructor === Array) {
+                this.distResults = [];
+                for (let item of data["DistResults"])
+                    this.distResults.push(EmpiricalDistResult.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): TTestResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new TTestResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["DegreeOfFreedom"] = this.degreeOfFreedom;
+        if (this.distResults && this.distResults.constructor === Array) {
+            data["DistResults"] = [];
+            for (let item of this.distResults)
+                data["DistResults"].push(item.toJSON());
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface ITTestResult extends IHypothesisTestResult {
+    degreeOfFreedom?: number | undefined;
+    distResults?: EmpiricalDistResult[] | undefined;
+}
+
+export enum Sorting2 {
+    Ascending = 0,
+    Descending = 1,
+}
+
+export class BinLabel implements IBinLabel {
+    value?: number | undefined;
+    minValue?: number | undefined;
+    maxValue?: number | undefined;
+    label?: string | undefined;
+
+    constructor(data?: IBinLabel) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.value = data["Value"];
+            this.minValue = data["MinValue"];
+            this.maxValue = data["MaxValue"];
+            this.label = data["Label"];
+        }
+    }
+
+    static fromJS(data: any): BinLabel {
+        data = typeof data === 'object' ? data : {};
+        let result = new BinLabel();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        data["MinValue"] = this.minValue;
+        data["MaxValue"] = this.maxValue;
+        data["Label"] = this.label;
+        return data;
+    }
+}
+
+export interface IBinLabel {
+    value?: number | undefined;
+    minValue?: number | undefined;
+    maxValue?: number | undefined;
+    label?: string | undefined;
+}
+
+export class PreProcessedString implements IPreProcessedString {
+    value?: string | undefined;
+    id?: number | undefined;
+    stringLookup?: { [key: string]: number; } | undefined;
+    indexLookup?: { [key: string]: string; } | undefined;
+
+    constructor(data?: IPreProcessedString) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.value = data["Value"];
+            this.id = data["Id"];
+            if (data["StringLookup"]) {
+                this.stringLookup = {};
+                for (let key in data["StringLookup"]) {
+                    if (data["StringLookup"].hasOwnProperty(key))
+                        this.stringLookup[key] = data["StringLookup"][key];
+                }
+            }
+            if (data["IndexLookup"]) {
+                this.indexLookup = {};
+                for (let key in data["IndexLookup"]) {
+                    if (data["IndexLookup"].hasOwnProperty(key))
+                        this.indexLookup[key] = data["IndexLookup"][key];
+                }
+            }
+        }
+    }
+
+    static fromJS(data: any): PreProcessedString {
+        data = typeof data === 'object' ? data : {};
+        let result = new PreProcessedString();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Value"] = this.value;
+        data["Id"] = this.id;
+        if (this.stringLookup) {
+            data["StringLookup"] = {};
+            for (let key in this.stringLookup) {
+                if (this.stringLookup.hasOwnProperty(key))
+                    data["StringLookup"][key] = this.stringLookup[key];
+            }
+        }
+        if (this.indexLookup) {
+            data["IndexLookup"] = {};
+            for (let key in this.indexLookup) {
+                if (this.indexLookup.hasOwnProperty(key))
+                    data["IndexLookup"][key] = this.indexLookup[key];
+            }
+        }
+        return data;
+    }
+}
+
+export interface IPreProcessedString {
+    value?: string | undefined;
+    id?: number | undefined;
+    stringLookup?: { [key: string]: number; } | undefined;
+    indexLookup?: { [key: string]: string; } | undefined;
+}
+
+export class BitSet implements IBitSet {
+    length?: number | undefined;
+    size?: number | undefined;
+
+    constructor(data?: IBitSet) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+            this.length = data["Length"];
+            this.size = data["Size"];
+        }
+    }
+
+    static fromJS(data: any): BitSet {
+        data = typeof data === 'object' ? data : {};
+        let result = new BitSet();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Length"] = this.length;
+        data["Size"] = this.size;
+        return data;
+    }
+}
+
+export interface IBitSet {
+    length?: number | undefined;
+    size?: number | undefined;
+}
+
+export class DateTimeUtil implements IDateTimeUtil {
+
+    constructor(data?: IDateTimeUtil) {
+        if (data) {
+            for (var property in data) {
+                if (data.hasOwnProperty(property))
+                    (<any>this)[property] = (<any>data)[property];
+            }
+        }
+    }
+
+    init(data?: any) {
+        if (data) {
+        }
+    }
+
+    static fromJS(data: any): DateTimeUtil {
+        data = typeof data === 'object' ? data : {};
+        let result = new DateTimeUtil();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        return data;
+    }
+}
+
+export interface IDateTimeUtil {
+}
+
+export class FrequentItemsetOperationParameters extends DistOperationParameters implements IFrequentItemsetOperationParameters {
+    filter?: string | undefined;
+    attributeParameters?: AttributeParameters[] | undefined;
+    attributeCodeParameters?: AttributeCaclculatedParameters[] | undefined;
+
+    constructor(data?: IFrequentItemsetOperationParameters) {
+        super(data);
+        this._discriminator = "FrequentItemsetOperationParameters";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            this.filter = data["Filter"];
+            if (data["AttributeParameters"] && data["AttributeParameters"].constructor === Array) {
+                this.attributeParameters = [];
+                for (let item of data["AttributeParameters"])
+                    this.attributeParameters.push(AttributeParameters.fromJS(item));
+            }
+            if (data["AttributeCodeParameters"] && data["AttributeCodeParameters"].constructor === Array) {
+                this.attributeCodeParameters = [];
+                for (let item of data["AttributeCodeParameters"])
+                    this.attributeCodeParameters.push(AttributeCaclculatedParameters.fromJS(item));
+            }
+        }
+    }
+
+    static fromJS(data: any): FrequentItemsetOperationParameters {
+        data = typeof data === 'object' ? data : {};
+        let result = new FrequentItemsetOperationParameters();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        data["Filter"] = this.filter;
+        if (this.attributeParameters && this.attributeParameters.constructor === Array) {
+            data["AttributeParameters"] = [];
+            for (let item of this.attributeParameters)
+                data["AttributeParameters"].push(item.toJSON());
+        }
+        if (this.attributeCodeParameters && this.attributeCodeParameters.constructor === Array) {
+            data["AttributeCodeParameters"] = [];
+            for (let item of this.attributeCodeParameters)
+                data["AttributeCodeParameters"].push(item.toJSON());
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IFrequentItemsetOperationParameters extends IDistOperationParameters {
+    filter?: string | undefined;
+    attributeParameters?: AttributeParameters[] | undefined;
+    attributeCodeParameters?: AttributeCaclculatedParameters[] | undefined;
+}
+
+export class FrequentItemsetResult extends Result implements IFrequentItemsetResult {
+    frequentItems?: { [key: string]: number; } | undefined;
+
+    constructor(data?: IFrequentItemsetResult) {
+        super(data);
+        this._discriminator = "FrequentItemsetResult";
+    }
+
+    init(data?: any) {
+        super.init(data);
+        if (data) {
+            if (data["FrequentItems"]) {
+                this.frequentItems = {};
+                for (let key in data["FrequentItems"]) {
+                    if (data["FrequentItems"].hasOwnProperty(key))
+                        this.frequentItems[key] = data["FrequentItems"][key];
+                }
+            }
+        }
+    }
+
+    static fromJS(data: any): FrequentItemsetResult {
+        data = typeof data === 'object' ? data : {};
+        let result = new FrequentItemsetResult();
+        result.init(data);
+        return result;
+    }
+
+    toJSON(data?: any) {
+        data = typeof data === 'object' ? data : {};
+        if (this.frequentItems) {
+            data["FrequentItems"] = {};
+            for (let key in this.frequentItems) {
+                if (this.frequentItems.hasOwnProperty(key))
+                    data["FrequentItems"][key] = this.frequentItems[key];
+            }
+        }
+        super.toJSON(data);
+        return data;
+    }
+}
+
+export interface IFrequentItemsetResult extends IResult {
+    frequentItems?: { [key: string]: number; } | undefined;
+}
+
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 8a52a501c..ac51a7d87 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -43,6 +43,8 @@ import { CurrentUserUtils } from '../../server/authentication/models/current_use
 import { Field, Opt } from '../../fields/Field';
 import { ListField } from '../../fields/ListField';
 import { map } from 'bluebird';
+import { Gateway, Settings } from '../northstar/manager/Gateway';
+import { Catalog } from '../northstar/model/idea/idea';
 
 @observer
 export class Main extends React.Component {
@@ -52,6 +54,7 @@ export class Main extends React.Component {
     @observable private userWorkspaces: Document[] = [];
     @observable public pwidth: number = 0;
     @observable public pheight: number = 0;
+    @observable private _northstarCatalog: Catalog | undefined = undefined;
 
     public mainDocId: string | undefined;
     private currentUser?: DashUserModel;
@@ -65,7 +68,9 @@ export class Main extends React.Component {
         if (window.location.pathname !== RouteStore.home) {
             let pathname = window.location.pathname.split("/");
             this.mainDocId = pathname[pathname.length - 1];
-        }
+        };
+
+        this.initializeNorthstar();
 
         CurrentUserUtils.loadCurrentUser();
 
@@ -82,9 +87,26 @@ export class Main extends React.Component {
         library.add(faMusic);
 
         this.initEventListeners();
-        Documents.initProtos(() => {
-            this.initAuthenticationRouters();
+        Documents.initProtos(() => this.initAuthenticationRouters());
+    }
+
+    @action SetNorthstarCatalog(ctlog: Catalog) {
+        this._northstarCatalog = ctlog;
+        if (this._northstarCatalog) {
+            console.log("CATALOG " + this._northstarCatalog.schemas);
+        }
+    }
+    async initializeNorthstar(): Promise<void> {
+        let envPath = "assets/env.json";
+        const response = await fetch(envPath, {
+            redirect: "follow",
+            method: "GET",
+            credentials: "include"
         });
+        const env = await response.json();
+        Settings.Instance.Update(env);
+        let cat = Gateway.Instance.ClearCatalog();
+        cat.then(async () => this.SetNorthstarCatalog(await Gateway.Instance.GetCatalog()));
     }
 
     onHistory = () => {
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 50f5e9618..062babe58 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -9,7 +9,6 @@ import { Field, Opt } from "../../../fields/Field";
 import { KeyStore } from "../../../fields/KeyStore";
 import { CompileScript, ToField } from "../../util/Scripting";
 import { Transform } from "../../util/Transform";
-import { ContextMenu } from "../ContextMenu";
 import { EditableView } from "../EditableView";
 import { DocumentView } from "../nodes/DocumentView";
 import { FieldView, FieldViewProps } from "../nodes/FieldView";
@@ -27,8 +26,7 @@ import { ListField } from "../../../fields/ListField";
 
 @observer
 class KeyToggle extends React.Component<{ keyId: string, checked: boolean, toggle: (key: Key) => void }> {
-    @observable
-    key: Key | undefined;
+    @observable key: Key | undefined;
 
     componentWillReceiveProps() {
         Server.GetField(this.props.keyId, action((field: Opt<Field>) => {
diff --git a/src/server/index.ts b/src/server/index.ts
index 6226dbfe2..d1eb6847d 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -18,7 +18,7 @@ import { getLogin, postLogin, getSignup, postSignup, getLogout, postReset, getFo
 const config = require('../../webpack.config');
 const compiler = webpack(config);
 const port = 1050; // default port to listen
-const serverPort = 1234;
+const serverPort = 4321;
 import * as expressValidator from 'express-validator';
 import expressFlash = require('express-flash');
 import flash = require('connect-flash');
diff --git a/webpack.config.js b/webpack.config.js
index ff03181c9..5ba9dd4b5 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -77,7 +77,7 @@ module.exports = {
     compress: false,
     host: "localhost",
     contentBase: path.join(__dirname, 'deploy'),
-    port: 1234,
+    port: 4321,
     hot: true,
     https: false,
     overlay: {
-- 
cgit v1.2.3-70-g09d2


From f2fa6d6d28f2011a13f9034f5685b08301c291e4 Mon Sep 17 00:00:00 2001
From: laurawilsonri <laura_wilson@brown.edu>
Date: Tue, 19 Mar 2019 16:48:10 -0400
Subject: ui much better

---
 src/client/views/Main.tsx                          |   1 +
 .../views/collections/CollectionSchemaView.scss    |  87 ++++++-------
 .../views/collections/CollectionSchemaView.tsx     | 143 ++++++---------------
 3 files changed, 77 insertions(+), 154 deletions(-)

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

diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 26a07fdfe..a6b893eca 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -78,6 +78,7 @@ export class Main extends React.Component {
         library.add(faFilm);
         library.add(faMusic);
 
+
         this.initEventListeners();
         Documents.initProtos(() => {
             this.initAuthenticationRouters();
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index d16f0edf9..8c2f62d43 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -1,66 +1,57 @@
+@import "../global_variables";
+
 //options menu styling
 #schemaOptionsMenuBtn {
     position: absolute;
-    height: 15px;
-    width: 15px;
+    height: 20px;
+    width: 20px;
     border-radius: 50%;
     z-index: 21; 
-    right: 3px;
-    top: 3px; 
+    right: 4px;
+    top: 4px; 
     pointer-events: auto;
-    background-color:red;
-}
-
-.dd-item-containter:hover {
-  background-color: rgb(204, 204, 204);
+    background-color:black;
+    display:inline-block;
+    padding: 0px;
+    font-size: 100%;
 }
-
-.dd-item {
-    color: black;
-    padding-left: 6px;
-    padding-bottom: 0px;
-    padding-top: 4px;
-    font-size: 12px;
+#schema-options-header {
+    text-align: center;
+    padding: 0px;
     margin: 0px;
-    display: block;
-    width: 100%;
-    height: 25px;
-    z-index: 100;
 }
-.dd-item:hover {
-    color: black;
-    font-weight: 500;
+.schema-options-subHeader {
+    color: $intermediate-color;
+    margin-bottom: 5px;
+}
+#schemaOptionsMenuBtn:hover {
+    transform: scale(1.15);
 }
 
-.dropdown-menu {
-    height: 100px;
-    overflow-y: scroll;
-  }
-
-#dropdown-basic-button {
-    background-color: #fff;
-    border: .75px solid #bbbbbb;
-    border-radius: 0;
-    -webkit-box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
-    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-    margin:10px;
-    margin-top: 8px;
-    color: black;
-    display: inline-block;
-    width: 160px;
-    height: 25px;
-    font-size: 15px;
-    padding: 0px;
-    border-radius: 3px;
-    font-size: 12px;
-  }
+#preview-schema-checkbox-div {
+    margin-left: 20px;
+    font-size: 11px;
+}
 
   #options-flyout-div {
-    text-align: center;
+    text-align: left;
     padding:0px;
+    z-index: 100;
+    font-family: $sans-serif;
+    padding-left: 5px;
+  }
+
+  #schema-col-checklist {
+    overflow: scroll;
+    text-align: left;
+    //background-color: $light-color-secondary;
+    line-height: 25px;
+    max-height: 175px;
+    font-family: $sans-serif;
+    font-size: 12px;
   }
   
-@import "../global_variables";
+
 .collectionSchemaView-container {
     border: 1px solid $intermediate-color;
     border-radius: $border-radius;
@@ -68,7 +59,7 @@
     position: absolute;
     width: 100%;
     height: 100%;
-    overflow: hidden;
+    
     .collectionSchemaView-content {
         position: absolute;
         height: 100%;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index da38d54c4..07b4d150a 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -19,10 +19,12 @@ import { CollectionViewBase } from "./CollectionViewBase";
 import { setupDrag } from "../../util/DragManager";
 import '../DocumentDecorations.scss';
 import { Flyout, anchorPoints } from "../DocumentDecorations";
-import { DropdownButton, Dropdown } from 'react-bootstrap';
 import { ListField } from "../../../fields/ListField";
 import { Key } from "../../../fields/Key";
 import { Server } from "../../Server";
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faCog } from '@fortawesome/free-solid-svg-icons';
 
 
 // bcz: need to add drag and drop of rows and columns.  This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
@@ -44,7 +46,7 @@ class KeyToggle extends React.Component<{ keyId: string, checked: boolean, toggl
     render() {
         if (this.key) {
             return (<div key={this.key.Id}>
-                <input type="checkbox" checked={this.props.checked} onChange={() => this.key && this.props.toggle(this.key)} />{this.key.Name}
+                <input type="checkbox" checked={this.props.checked} onChange={() => this.key && this.props.toggle(this.key)} />  {this.key.Name}
             </div>)
         } else {
             return <div></div>
@@ -66,6 +68,7 @@ export class CollectionSchemaView extends CollectionViewBase {
     @observable _columnsPercentage = 0;
     @computed get splitPercentage() { return this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0); }
 
+
     renderCell = (rowProps: CellInfo) => {
         let props: FieldViewProps = {
             doc: rowProps.value[0],
@@ -156,6 +159,15 @@ export class CollectionSchemaView extends CollectionViewBase {
             })
     }
 
+    //toggles preview side-panel of schema
+    @action
+    toggleExpander = (event: React.ChangeEvent<HTMLInputElement>) => {
+        this._startSplitPercent = this.splitPercentage;
+        if (this._startSplitPercent == this.splitPercentage) {
+            this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0);
+        }
+    }
+
     @observable keys: Key[] = [];
 
     findAllDocumentKeys = (): { [id: string]: boolean } => {
@@ -220,37 +232,6 @@ export class CollectionSchemaView extends CollectionViewBase {
         e.stopPropagation();
         e.preventDefault();
     }
-    @action
-    onExpanderUp = (e: PointerEvent): void => {
-        e.stopPropagation();
-        e.preventDefault();
-        document.removeEventListener("pointermove", this.onExpanderMove);
-        document.removeEventListener('pointerup', this.onExpanderUp);
-        if (this._startSplitPercent == this.splitPercentage) {
-            this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0);
-        }
-    }
-    onExpanderDown = (e: React.PointerEvent) => {
-        this._startSplitPercent = this.splitPercentage;
-        e.stopPropagation();
-        e.preventDefault();
-        document.addEventListener("pointermove", this.onExpanderMove);
-        document.addEventListener('pointerup', this.onExpanderUp);
-    }
-
-    onPointerDown = (e: React.PointerEvent) => {
-        // if (e.button === 2 && this.active) {
-        //     e.stopPropagation();
-        //     e.preventDefault();
-        // } else 
-        {
-            // if (e.buttons === 1) {
-            //     if (this.props.isSelected()) {
-            //         e.stopPropagation();
-            //     }
-            // }
-        }
-    }
 
     @action
     onColumnsMove = (e: PointerEvent): void => {
@@ -291,23 +272,16 @@ export class CollectionSchemaView extends CollectionViewBase {
 
     focusDocument = (doc: Document) => { }
 
-    keyDropDownOnSelect = (keyId: string) => {
-        const columns = this.props.Document.GetList(KeyStore.ColumnsKey, [KeyStore.Title, KeyStore.Data, KeyStore.Author]);
-        const listOfFields = this.props.Document.GetList<Document>(this.props.fieldKey, [])[1].fields;
-        if (listOfFields.has(keyId)) {
-            let index = columns.push(listOfFields!.get(keyId)!.key);
-            this.props.Document.SetData(KeyStore.ColumnsKey, columns, ListField);
-        }
-    }
-
-    dropdownItemOnPointerDown = (e: React.PointerEvent): void => {
-        //(e.currentTarget.children[0] as Dropdown.Item ).onSelect();
+    onPointerDown = (e: React.PointerEvent): void => {
+        //
     }
 
     render() {
+        library.add(faCog);
         const columns = this.columns;
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
         const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined;
+        //all the keys/columns that will be displayed in the schema
         const allKeys = this.findAllDocumentKeys();
         let content = this._selectedIndex == -1 || !selected ? (null) : (
             <Measure onResize={this.setScaling}>
@@ -328,53 +302,28 @@ export class CollectionSchemaView extends CollectionViewBase {
                 }
             </Measure>
         )
-        let previewHandle = !this.props.active() ? (null) : (
-            <div className="collectionSchemaView-previewHandle" onPointerDown={this.onExpanderDown} />);
-        let columnsHandle = !this.props.active() ? (null) : (
-            <div className="collectionSchemaView-columnsHandle" onPointerDown={this.onColumnsDown} />);
         let dividerDragger = this.splitPercentage == 0 ? (null) :
             <div className="collectionSchemaView-dividerDragger" onPointerDown={this.onDividerDown} style={{ width: `${this.DIVIDER_WIDTH}px` }} />
 
-        //get the union of all childrens' keys
-        let addFields: { id: string, name: string }[] = [];
-        let removeFields: { id: string, name: string }[] = [];
-        let optionsMenu = null;
-        if (this.props.active()) {
-            let protos = this.props.Document.GetAllPrototypes();
-            for (const proto of protos) {
-                proto._proxies.forEach((val, key) => {
-                    if (!(key in addFields.keys)) {
-                        let this_name: string = proto.fields!.get(key)!.key.Name;
-                        addFields.push({ id: key, name: this_name });
-                    }
-                })
-            }
-            /*<DropdownButton id="dropdown-basic-button" className="colDropDown" title="Add Column">
-                        {addFields.map(({ id, name }) => (
-                            <div className="dd-item-containter"><Dropdown.Item className="dd-item" eventKey={id} onSelect={this.keyDropDownOnSelect}>{name} </Dropdown.Item></div>))}
-                    </DropdownButton>
-                    <DropdownButton id="dropdown-basic-button" className="colDropDown" title="Remove Column">
-                        {addFields.map(({ id, name }) => (
-                            <div className="dd-item-containter"><Dropdown.Item className="dd-item" eventKey={id} onSelect={this.keyDropDownOnSelect}>{name} </Dropdown.Item></div>))}
-                    </DropdownButton>*/
-            optionsMenu = !this.props.active() ? (null) : (<Flyout
-                anchorPoint={anchorPoints.LEFT_TOP}
-                content={<div id="options-flyout-div"> <h5>Options</h5>
-                    <div className="addColumn-options">
-                        <ul style={{ overflow: "scroll" }}>
-                            {Array.from(Object.keys(allKeys)).map(item => {
-                                return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
-                            })}
-                        </ul>
-                    </div>
+        //options button and menu
+        let optionsMenu = !this.props.active() ? (null) : (<Flyout
+            anchorPoint={anchorPoints.LEFT_TOP}
+            content={<div>
+                <div id="schema-options-header"><h5><b>Options</b></h5></div>
+                <div id="options-flyout-div">
+                    <h6 className="schema-options-subHeader">Preview Window</h6>
+                    <div id="preview-schema-checkbox-div"><input type="checkbox" key={"Show Preview"} checked={this.splitPercentage != 0} onChange={this.toggleExpander} />  Show Preview </div>
+                    <h6 className="schema-options-subHeader" >Displayed Columns</h6>
+                    <ul id="schema-col-checklist" >
+                        {Array.from(Object.keys(allKeys)).map(item => {
+                            return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
+                        })}
+                    </ul>
                 </div>
-                }>
-                <div id="schemaOptionsMenuBtn" />
-            </Flyout>);
-        }
-
-        let colDividerDragger = this._columnsPercentage == 0 ? (null) :
-            <div className="collectionSchemaView-colDividerDragger" onPointerDown={this.onColDividerDown} style={{ height: `${this.DIVIDER_WIDTH}px` }} />
+            </div>
+            }>
+            <button id="schemaOptionsMenuBtn"><FontAwesomeIcon style={{ color: "white" }} icon="cog" size="sm" /></button>
+        </Flyout>);
 
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
@@ -412,27 +361,9 @@ export class CollectionSchemaView extends CollectionViewBase {
                     <div className="collectionSchemaView-previewRegion" style={{ width: `calc(${this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0)}% - ${this.DIVIDER_WIDTH}px)` }}>
                         {content}
                     </div>
-                    {previewHandle}
-
-                    {columnsHandle}
                     {optionsMenu}
                 </div>
             </div >
         )
     }
-}
-/*
-{colDividerDragger}
-                                <div className="collectionSchemaView-addColumn" style={{ height: `${this._columnsPercentage}%` }} >
-                                    {/* <input type="checkbox" id="addColumn-toggle" />
-                                    <label htmlFor="addColumn-toggle" title="Add Column"><p>+</p></label> }
-
-                                    <div className="addColumn-options">
-                                        <ul style={{ overflow: "scroll" }}>
-                                            {Array.from(Object.keys(allKeys)).map(item => {
-                                                return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
-                                            })}
-                                        </ul>
-                                    </div>
-                                </div>
-                                */
\ No newline at end of file
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 79846f5e85c04435082106724d49b03eea31657f Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 21 Mar 2019 00:57:02 -0400
Subject: minor fix to schema dragger and treeview

---
 src/client/views/collections/CollectionSchemaView.tsx | 2 +-
 src/client/views/collections/CollectionTreeView.tsx   | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index c2645ea73..d3ade7ebb 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -189,7 +189,7 @@ export class CollectionSchemaView extends CollectionViewBase {
     @action
     onDividerMove = (e: PointerEvent): void => {
         let nativeWidth = this._mainCont.current!.getBoundingClientRect();
-        this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, 100 - Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100));
+        this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, Math.max(0, 100 - Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100)));
     }
     @action
     onDividerUp = (e: PointerEvent): void => {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 6edd90215..ec1bf5d0e 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,7 +1,7 @@
 import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
 import { faCaretDown, faCaretRight, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, observable } from "mobx";
+import { action, observable, trace } from "mobx";
 import { observer } from "mobx-react";
 import { Document } from "../../../fields/Document";
 import { FieldWaiting } from "../../../fields/Field";
@@ -90,14 +90,14 @@ class TreeView extends React.Component<TreeViewProps> {
         if (children && children !== FieldWaiting) { // add children for a collection
             if (!this._collapsed) {
                 bulletType = BulletType.Collapsible;
-                childElements = <ul key={this.props.document.Id}>
+                childElements = <ul>
                     {children.Data.map(value => <TreeView key={value.Id} document={value} deleteDoc={this.remove} />)}
                 </ul>
             }
             else bulletType = BulletType.Collapsed;
         }
         return <div className="treeViewItem-container" >
-            <li className="collection-child" key={this.props.document.Id}>
+            <li className="collection-child">
                 {this.renderBullet(bulletType)}
                 {this.renderTitle()}
                 {childElements ? childElements : (null)}
-- 
cgit v1.2.3-70-g09d2


From 18ef731f66340c759f6818c923e1032bd5b84c7a Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 21 Mar 2019 01:50:48 -0400
Subject: fixed selections within schema.  fixed image double-tap.  fixed Open
 Full Screen

---
 .../views/collections/CollectionDockingView.tsx    |   2 +
 .../views/collections/CollectionSchemaView.tsx     | 151 +++++++--------------
 src/client/views/nodes/ImageBox.tsx                |   4 +-
 3 files changed, 53 insertions(+), 104 deletions(-)

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

diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 0f0276929..fd0810242 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -61,6 +61,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         docconfig.callDownwards('_$init');
         this._goldenLayout._$maximiseItem(docconfig);
         this._fullScreen = docconfig;
+        this._ignoreStateChange = JSON.stringify(this._goldenLayout.toConfig());
         this.stateChanged();
     }
     @action
@@ -69,6 +70,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
             this._goldenLayout._$minimiseItem(this._fullScreen);
             this._goldenLayout.root.contentItems[0].removeChild(this._fullScreen);
             this._fullScreen = null;
+            this._ignoreStateChange = JSON.stringify(this._goldenLayout.toConfig());
             this.stateChanged();
         }
     }
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index d3ade7ebb..b986f394c 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,29 +1,29 @@
 import React = require("react")
-import { action, observable, ObservableMap, computed } from "mobx";
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { faCog } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
 import Measure from "react-measure";
 import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
 import "react-table/react-table.css";
 import { Document } from "../../../fields/Document";
 import { Field, Opt } from "../../../fields/Field";
+import { Key } from "../../../fields/Key";
 import { KeyStore } from "../../../fields/KeyStore";
+import { ListField } from "../../../fields/ListField";
+import { Server } from "../../Server";
+import { setupDrag } from "../../util/DragManager";
 import { CompileScript, ToField } from "../../util/Scripting";
 import { Transform } from "../../util/Transform";
+import { anchorPoints, Flyout } from "../DocumentDecorations";
+import '../DocumentDecorations.scss';
 import { EditableView } from "../EditableView";
 import { DocumentView } from "../nodes/DocumentView";
 import { FieldView, FieldViewProps } from "../nodes/FieldView";
 import "./CollectionSchemaView.scss";
-import { COLLECTION_BORDER_WIDTH, CollectionView } from "./CollectionView";
+import { CollectionView, COLLECTION_BORDER_WIDTH } from "./CollectionView";
 import { CollectionViewBase } from "./CollectionViewBase";
-import { setupDrag } from "../../util/DragManager";
-import '../DocumentDecorations.scss';
-import { Flyout, anchorPoints } from "../DocumentDecorations";
-import { ListField } from "../../../fields/ListField";
-import { Key } from "../../../fields/Key";
-import { Server } from "../../Server";
-import { library } from '@fortawesome/fontawesome-svg-core';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faCog } from '@fortawesome/free-solid-svg-icons';
 
 
 // bcz: need to add drag and drop of rows and columns.  This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
@@ -44,17 +44,18 @@ class KeyToggle extends React.Component<{ keyId: string, checked: boolean, toggl
     render() {
         if (this.key) {
             return (<div key={this.key.Id}>
-                <input type="checkbox" checked={this.props.checked} onChange={() => this.key && this.props.toggle(this.key)} />  {this.key.Name}
+                <input type="checkbox" checked={this.props.checked} onChange={() => this.key && this.props.toggle(this.key)} />
+                {this.key.Name}
             </div>)
-        } else {
-            return <div></div>
         }
+        return (null);
     }
 }
 
 @observer
 export class CollectionSchemaView extends CollectionViewBase {
     private _mainCont = React.createRef<HTMLDivElement>();
+    private _startSplitPercent = 0;
     private DIVIDER_WIDTH = 4;
 
     @observable _columns: Array<Key> = [KeyStore.Title, KeyStore.Data, KeyStore.Author];
@@ -64,6 +65,8 @@ export class CollectionSchemaView extends CollectionViewBase {
     @observable _panelHeight = 0;
     @observable _selectedIndex = 0;
     @observable _columnsPercentage = 0;
+    @observable _keys: Key[] = [];
+
     @computed get splitPercentage() { return this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0); }
 
 
@@ -124,9 +127,8 @@ export class CollectionSchemaView extends CollectionViewBase {
         }
         return {
             onClick: action((e: React.MouseEvent, handleOriginal: Function) => {
+                that.props.select(e.ctrlKey);
                 that._selectedIndex = rowInfo.index;
-                // bcz - ugh - needed to force Measure to do its thing and call onResize
-                this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage - 0.05)
 
                 if (handleOriginal) {
                     handleOriginal()
@@ -165,27 +167,14 @@ export class CollectionSchemaView extends CollectionViewBase {
             this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0);
         }
     }
-
-    @observable keys: Key[] = [];
-
     findAllDocumentKeys = (): { [id: string]: boolean } => {
         const docs = this.props.Document.GetList<Document>(this.props.fieldKey, []);
         let keys: { [id: string]: boolean } = {}
-        docs.forEach(doc => {
-            let protos = doc.GetAllPrototypes();
-            for (const proto of protos) {
-                proto._proxies.forEach((val: any, key: string) => {
-                    keys[key] = false
-                })
-            }
-        })
-        this.columns.forEach(key => {
-            keys[key.Id] = true;
-        })
+        docs.map(doc => doc.GetAllPrototypes().map(proto => proto._proxies.forEach((val: any, key: string) => keys[key] = false)));
+        this.columns.forEach(key => keys[key.Id] = true)
         return keys;
     }
 
-    _startSplitPercent = 0;
     @action
     onDividerMove = (e: PointerEvent): void => {
         let nativeWidth = this._mainCont.current!.getBoundingClientRect();
@@ -207,51 +196,11 @@ export class CollectionSchemaView extends CollectionViewBase {
         document.addEventListener('pointerup', this.onDividerUp);
     }
 
-
+    @observable _tableWidth = 0;
     @action
-    onColDividerMove = (e: PointerEvent): void => {
-        let nativeWidth = this._mainCont.current!.getBoundingClientRect();
-        this._columnsPercentage = 100 - (e.clientY - nativeWidth.top) / nativeWidth.height * 100;
+    setTableDimensions = (r: any) => {
+        this._tableWidth = r.entry.width;
     }
-    @action
-    onColDividerUp = (e: PointerEvent): void => {
-        document.removeEventListener("pointermove", this.onColDividerMove);
-        document.removeEventListener('pointerup', this.onColDividerUp);
-    }
-    onColDividerDown = (e: React.PointerEvent) => {
-        e.stopPropagation();
-        e.preventDefault();
-        document.addEventListener("pointermove", this.onColDividerMove);
-        document.addEventListener('pointerup', this.onColDividerUp);
-    }
-
-    @action
-    onExpanderMove = (e: PointerEvent): void => {
-        e.stopPropagation();
-        e.preventDefault();
-    }
-
-    @action
-    onColumnsMove = (e: PointerEvent): void => {
-        e.stopPropagation();
-        e.preventDefault();
-    }
-    @action
-    onColumnsUp = (e: PointerEvent): void => {
-        e.stopPropagation();
-        e.preventDefault();
-        document.removeEventListener("pointermove", this.onColumnsMove);
-        document.removeEventListener('pointerup', this.onColumnsUp);
-        this._columnsPercentage = this._columnsPercentage ? 0 : 50;
-    }
-    onColumnsDown = (e: React.PointerEvent) => {
-        this._startSplitPercent = this.splitPercentage;
-        e.stopPropagation();
-        e.preventDefault();
-        document.addEventListener("pointermove", this.onColumnsMove);
-        document.addEventListener('pointerup', this.onColumnsUp);
-    }
-
     @action
     setScaling = (r: any) => {
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
@@ -267,11 +216,16 @@ export class CollectionSchemaView extends CollectionViewBase {
     getTransform = (): Transform => {
         return this.props.ScreenToLocalTransform().translate(- COLLECTION_BORDER_WIDTH - this.DIVIDER_WIDTH - this._dividerX, - COLLECTION_BORDER_WIDTH).scale(1 / this._contentScaling);
     }
+    getPreviewTransform = (): Transform => {
+        return this.props.ScreenToLocalTransform().translate(- COLLECTION_BORDER_WIDTH - this.DIVIDER_WIDTH - this._dividerX - this._tableWidth, - COLLECTION_BORDER_WIDTH).scale(1 / this._contentScaling);
+    }
 
     focusDocument = (doc: Document) => { }
 
     onPointerDown = (e: React.PointerEvent): void => {
-        //
+        if (this.props.isSelected()) {
+            e.stopPropagation();
+        }
     }
 
     render() {
@@ -289,7 +243,7 @@ export class CollectionSchemaView extends CollectionViewBase {
                             AddDocument={this.props.addDocument} RemoveDocument={this.props.removeDocument}
                             isTopMost={false}
                             SelectOnLoad={false}
-                            ScreenToLocalTransform={this.getTransform}
+                            ScreenToLocalTransform={this.getPreviewTransform}
                             ContentScaling={this.getContentScaling}
                             PanelWidth={this.getPanelWidth}
                             PanelHeight={this.getPanelHeight}
@@ -326,34 +280,27 @@ export class CollectionSchemaView extends CollectionViewBase {
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
                 <div className="collectionSchemaView-dropTarget" onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}>
-                    <Measure onResize={action((r: any) => {
-                        this._dividerX = r.entry.width;
-                        this._panelHeight = r.entry.height;
-                    })}>
+                    <Measure onResize={this.setTableDimensions}>
                         {({ measureRef }) =>
-                            <div ref={measureRef} className="collectionSchemaView-tableContainer"
-                                style={{ width: `calc(100% - ${this.splitPercentage}%)` }}>
-                                <div className="collectionSchemaView-reactContainer" style={{ height: `calc(100% - ${this._columnsPercentage}%)` }}>
-                                    <ReactTable
-                                        data={children}
-                                        pageSize={children.length}
-                                        page={0}
-                                        showPagination={false}
-                                        columns={columns.map(col => ({
-                                            Header: col.Name,
-                                            accessor: (doc: Document) => [doc, col],
-                                            id: col.Id
-                                        }))}
-                                        column={{
-                                            ...ReactTableDefaults.column,
-                                            Cell: this.renderCell,
+                            <div className="collectionSchemaView-tableContainer" ref={measureRef} style={{ width: `calc(100% - ${this.splitPercentage}%)` }}>
+                                <ReactTable
+                                    data={children}
+                                    pageSize={children.length}
+                                    page={0}
+                                    showPagination={false}
+                                    columns={columns.map(col => ({
+                                        Header: col.Name,
+                                        accessor: (doc: Document) => [doc, col],
+                                        id: col.Id
+                                    }))}
+                                    column={{
+                                        ...ReactTableDefaults.column,
+                                        Cell: this.renderCell,
 
-                                        }}
-                                        getTrProps={this.getTrProps}
-                                    />
-                                </div>
-                            </div>
-                        }
+                                    }}
+                                    getTrProps={this.getTrProps}
+                                />
+                            </div>}
                     </Measure>
                     {dividerDragger}
                     <div className="collectionSchemaView-previewRegion" style={{ width: `calc(${this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0)}% - ${this.DIVIDER_WIDTH}px)` }}>
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 2db0cc4e2..60d1f7214 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -50,7 +50,7 @@ export class ImageBox extends React.Component<FieldViewProps> {
 
     onPointerDown = (e: React.PointerEvent): void => {
         if (Date.now() - this._lastTap < 300) {
-            if (e.buttons === 1 && this.props.isSelected()) {
+            if (e.buttons === 1) {
                 e.stopPropagation();
                 this._downX = e.clientX;
                 this._downY = e.clientY;
@@ -72,7 +72,7 @@ export class ImageBox extends React.Component<FieldViewProps> {
 
     lightbox = (path: string) => {
         const images = [path];
-        if (this._isOpen && this.props.isSelected()) {
+        if (this._isOpen) {
             return (<Lightbox
                 mainSrc={images[this._photoIndex]}
                 nextSrc={images[(this._photoIndex + 1) % images.length]}
-- 
cgit v1.2.3-70-g09d2


From 08c35582dc71623c2b7300458238b6ba25ff98d7 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 21 Mar 2019 15:30:15 -0400
Subject: fixed performance problem with loading schema with a lot of
 documents.

---
 .../views/collections/CollectionSchemaView.tsx     | 25 +++++++++++++++++-----
 .../views/collections/CollectionTreeView.tsx       |  2 +-
 2 files changed, 21 insertions(+), 6 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index b986f394c..34b019244 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -2,7 +2,7 @@ import React = require("react")
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faCog } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable } from "mobx";
+import { action, computed, observable, trace, untracked } from "mobx";
 import { observer } from "mobx-react";
 import Measure from "react-measure";
 import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
@@ -141,6 +141,7 @@ export class CollectionSchemaView extends CollectionViewBase {
         };
     }
 
+    @computed
     get columns() {
         return this.props.Document.GetList<Key>(KeyStore.ColumnsKey, []);
     }
@@ -167,10 +168,19 @@ export class CollectionSchemaView extends CollectionViewBase {
             this.props.Document.SetNumber(KeyStore.SchemaSplitPercentage, this.splitPercentage == 0 ? 33 : 0);
         }
     }
-    findAllDocumentKeys = (): { [id: string]: boolean } => {
+
+    @computed
+    get findAllDocumentKeys(): { [id: string]: boolean } {
         const docs = this.props.Document.GetList<Document>(this.props.fieldKey, []);
         let keys: { [id: string]: boolean } = {}
-        docs.map(doc => doc.GetAllPrototypes().map(proto => proto._proxies.forEach((val: any, key: string) => keys[key] = false)));
+        if (this._optionsActivated > -1) {
+            // bcz: ugh.  this is untracked since otherwise a large collection of documents will blast the server for all their fields.
+            //  then as each document's fields come back, we update the documents _proxies.  Each time we do this, the whole schema will be
+            //  invalidated and re-rendered.   This workaround will inquire all of the document fields before the options button is clicked.
+            //  then by the time the options button is clicked, all of the fields should be in place.  If a new field is added while this menu
+            //  is displayed (unlikely) it won't show up until something else changes.
+            untracked(() => docs.map(doc => doc.GetAllPrototypes().map(proto => proto._proxies.forEach((val: any, key: string) => keys[key] = false))));
+        }
         this.columns.forEach(key => keys[key.Id] = true)
         return keys;
     }
@@ -228,13 +238,18 @@ export class CollectionSchemaView extends CollectionViewBase {
         }
     }
 
+    @observable _optionsActivated: number = 0;
+    @action
+    OptionsMenuDown = (e: React.PointerEvent) => {
+        this._optionsActivated++;
+    }
     render() {
         library.add(faCog);
         const columns = this.columns;
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
         const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined;
         //all the keys/columns that will be displayed in the schema
-        const allKeys = this.findAllDocumentKeys();
+        const allKeys = this.findAllDocumentKeys;
         let content = this._selectedIndex == -1 || !selected ? (null) : (
             <Measure onResize={this.setScaling}>
                 {({ measureRef }) =>
@@ -274,7 +289,7 @@ export class CollectionSchemaView extends CollectionViewBase {
                 </div>
             </div>
             }>
-            <button id="schemaOptionsMenuBtn"><FontAwesomeIcon style={{ color: "white" }} icon="cog" size="sm" /></button>
+            <button id="schemaOptionsMenuBtn" onPointerDown={this.OptionsMenuDown}><FontAwesomeIcon style={{ color: "white" }} icon="cog" size="sm" /></button>
         </Flyout>);
 
         return (
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index ec1bf5d0e..6cc14ebcb 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -76,7 +76,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 }}
             />);
         return (
-            <div key={this.props.document.Id} className="docContainer" ref={reference} onPointerDown={onItemDown}>
+            <div className="docContainer" ref={reference} onPointerDown={onItemDown}>
                 {editableView(this.props.document.Title)}
                 <div className="delete-button" onClick={this.delete}><FontAwesomeIcon icon="trash-alt" size="xs" /></div>
             </div >)
-- 
cgit v1.2.3-70-g09d2


From 619c01891713b0ceb889ab45659b35f4b9fbc7e3 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Fri, 22 Mar 2019 07:15:22 -0400
Subject: Added basic fill down to schema view

---
 src/client/util/Scripting.ts                       |  2 +-
 src/client/util/type_decls.d                       |  7 ++++
 src/client/views/EditableView.tsx                  | 11 +++++-
 .../views/collections/CollectionSchemaView.tsx     | 43 ++++++++++++++--------
 src/fields/Document.ts                             |  8 +++-
 5 files changed, 51 insertions(+), 20 deletions(-)

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

diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index 46bd1a206..4cf98472f 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -110,7 +110,7 @@ export function CompileScript(script: string, scope?: { [name: string]: any }, a
     let host = new ScriptingCompilerHost;
     let funcScript = `(function() {
         ${addReturn ? `return ${script};` : script}
-    })()`
+    }).apply(this)`
     host.writeFile("file.ts", funcScript);
     host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib);
     let program = ts.createProgram(["file.ts"], {}, host);
diff --git a/src/client/util/type_decls.d b/src/client/util/type_decls.d
index 679f73f42..dcf79285d 100644
--- a/src/client/util/type_decls.d
+++ b/src/client/util/type_decls.d
@@ -213,3 +213,10 @@ declare class Document extends Field {
     GetAllPrototypes(): Document[];
     MakeDelegate(): Document;
 }
+
+declare const KeyStore: {
+    [name: string]: Key;
+}
+
+// @ts-ignore
+declare const console: any;
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 579d6e6ad..29bf6add7 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -16,6 +16,8 @@ export interface EditableProps {
      *  */
     SetValue(value: string): boolean;
 
+    OnFillDown?(value: string): void;
+
     /**
      * The contents to render when not editing
      */
@@ -36,8 +38,13 @@ export class EditableView extends React.Component<EditableProps> {
 
     @action
     onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
-        if (e.key == "Enter" && !e.ctrlKey) {
-            if (this.props.SetValue(e.currentTarget.value)) {
+        if (e.key == "Enter") {
+            if (!e.ctrlKey) {
+                if (this.props.SetValue(e.currentTarget.value)) {
+                    this.editing = false;
+                }
+            } else if (this.props.OnFillDown) {
+                this.props.OnFillDown(e.currentTarget.value);
                 this.editing = false;
             }
         } else if (e.key == "Escape") {
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 34b019244..8e0a38f05 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -85,12 +85,31 @@ export class CollectionSchemaView extends CollectionViewBase {
         )
         let reference = React.createRef<HTMLDivElement>();
         let onItemDown = setupDrag(reference, () => props.doc, (containingCollection: CollectionView) => this.props.removeDocument(props.doc));
+        let applyToDoc = (doc: Document, value: string) => {
+            let script = CompileScript(value, { this: doc }, true);
+            if (!script.compiled) {
+                return false;
+            }
+            let field = script();
+            if (field instanceof Field) {
+                doc.Set(props.fieldKey, field);
+                return true;
+            } else {
+                let dataField = ToField(field);
+                if (dataField) {
+                    doc.Set(props.fieldKey, dataField);
+                    return true;
+                }
+            }
+            return false;
+        }
         return (
             <div className="collectionSchemaView-cellContents" onPointerDown={onItemDown} style={{ height: "36px" }} key={props.doc.Id} ref={reference}>
                 <EditableView
                     display={"inline"}
                     contents={contents}
-                    height={36} GetValue={() => {
+                    height={36}
+                    GetValue={() => {
                         let field = props.doc.Get(props.fieldKey);
                         if (field && field instanceof Field) {
                             return field.ToScriptString();
@@ -98,22 +117,14 @@ export class CollectionSchemaView extends CollectionViewBase {
                         return field || "";
                     }}
                     SetValue={(value: string) => {
-                        let script = CompileScript(value);
-                        if (!script.compiled) {
-                            return false;
-                        }
-                        let field = script();
-                        if (field instanceof Field) {
-                            props.doc.Set(props.fieldKey, field);
-                            return true;
-                        } else {
-                            let dataField = ToField(field);
-                            if (dataField) {
-                                props.doc.Set(props.fieldKey, dataField);
-                                return true;
+                        return applyToDoc(props.doc, value);
+                    }}
+                    OnFillDown={(value: string) => {
+                        this.props.Document.GetTAsync<ListField<Document>>(this.props.fieldKey, ListField).then((val) => {
+                            if (val) {
+                                val.Data.forEach(doc => applyToDoc(doc, value));
                             }
-                        }
-                        return false;
+                        })
                     }}>
                 </EditableView>
             </div>
diff --git a/src/fields/Document.ts b/src/fields/Document.ts
index fc4906d17..d098cc96d 100644
--- a/src/fields/Document.ts
+++ b/src/fields/Document.ts
@@ -132,7 +132,13 @@ export class Document extends Field {
         } else if (this._proxies.has(key.Id)) {
             Server.GetDocumentField(this, key, callback);
         } else {
-            callback(undefined);
+            this.GetTAsync(KeyStore.Prototype, Document, proto => {
+                if (proto) {
+                    proto.GetAsync(key, callback);
+                } else {
+                    callback(undefined);
+                }
+            })
         }
     }
 
-- 
cgit v1.2.3-70-g09d2


From 1238c172a2ac9fb7dfdee2588f141f2ae0c22b8e Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 22 Mar 2019 08:54:37 -0400
Subject: fixed schema scrolling

---
 src/client/views/collections/CollectionSchemaView.tsx | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 34b019244..696527049 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -238,6 +238,11 @@ export class CollectionSchemaView extends CollectionViewBase {
         }
     }
 
+    onWheel = (e: React.WheelEvent): void => {
+        if (this.props.active())
+            e.stopPropagation();
+    }
+
     @observable _optionsActivated: number = 0;
     @action
     OptionsMenuDown = (e: React.PointerEvent) => {
@@ -293,7 +298,7 @@ export class CollectionSchemaView extends CollectionViewBase {
         </Flyout>);
 
         return (
-            <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
+            <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} onWheel={this.onWheel} ref={this._mainCont} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} >
                 <div className="collectionSchemaView-dropTarget" onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}>
                     <Measure onResize={this.setTableDimensions}>
                         {({ measureRef }) =>
-- 
cgit v1.2.3-70-g09d2


From 356991c6100a44ef45b4574b43c815383d9be751 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Sat, 23 Mar 2019 00:22:52 -0400
Subject: Various fixes for the demo

---
 src/client/documents/Documents.ts                  | 17 ++++++---
 src/client/util/Scripting.ts                       |  8 +++--
 src/client/util/type_decls.d                       |  3 ++
 .../views/collections/CollectionFreeFormView.tsx   |  5 +++
 .../views/collections/CollectionSchemaView.tsx     | 42 ++++++++++++++++++----
 .../views/collections/CollectionViewBase.tsx       | 39 ++++++++++++++------
 src/client/views/nodes/DocumentView.tsx            |  7 ++++
 src/client/views/nodes/FieldView.tsx               | 18 +++++++++-
 src/client/views/nodes/FormattedTextBox.tsx        |  2 ++
 9 files changed, 117 insertions(+), 24 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 96a7332aa..a2444db06 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,6 +1,6 @@
 import { AudioField } from "../../fields/AudioField";
 import { Document } from "../../fields/Document";
-import { Field } from "../../fields/Field";
+import { Field, FieldWaiting } from "../../fields/Field";
 import { HtmlField } from "../../fields/HtmlField";
 import { ImageField } from "../../fields/ImageField";
 import { InkField, StrokeData } from "../../fields/InkField";
@@ -23,6 +23,7 @@ import { PDFBox } from "../views/nodes/PDFBox";
 import { VideoBox } from "../views/nodes/VideoBox";
 import { WebBox } from "../views/nodes/WebBox";
 import { HistogramBox } from "../views/nodes/HistogramBox";
+import { FieldView } from "../views/nodes/FieldView";
 
 export interface DocumentOptions {
     x?: number;
@@ -112,7 +113,7 @@ export namespace Documents {
     function GetImagePrototype(): Document {
         if (!imageProto) {
             imageProto = setupPrototypeOptions(imageProtoId, "IMAGE_PROTO", CollectionView.LayoutString("AnnotationsKey"),
-                { x: 0, y: 0, nativeWidth: 300, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] });
+                { x: 0, y: 0, nativeWidth: 300, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
             imageProto.SetText(KeyStore.BackgroundLayout, ImageBox.LayoutString());
         }
         return imageProto;
@@ -155,7 +156,7 @@ export namespace Documents {
     function GetVideoPrototype(): Document {
         if (!videoProto) {
             videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("AnnotationsKey"),
-                { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] });
+                { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] });
             videoProto.SetNumber(KeyStore.CurPage, 0);
             videoProto.SetText(KeyStore.BackgroundLayout, VideoBox.LayoutString());
         }
@@ -218,6 +219,14 @@ export namespace Documents {
         return assignToDelegate(SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Docking }, [config, TextField], id), options)
     }
 
+    export function CaptionDocument(doc: Document) {
+        const captionDoc = doc.CreateAlias();
+        captionDoc.SetText(KeyStore.OverlayLayout, FixedCaption());
+        captionDoc.SetNumber(KeyStore.Width, doc.GetNumber(KeyStore.Width, 0));
+        captionDoc.SetNumber(KeyStore.Height, doc.GetNumber(KeyStore.Height, 0));
+        return captionDoc;
+    }
+
     // example of custom display string for an image that shows a caption.
     function EmbeddedCaption() {
         return `<div style="height:100%">
@@ -228,7 +237,7 @@ export namespace Documents {
             + FormattedTextBox.LayoutString("CaptionKey") +
             `</div> 
         </div>` };
-    function FixedCaption(fieldName: string = "Caption") {
+    export function FixedCaption(fieldName: string = "Caption") {
         return `<div style="position:absolute; height:30px; bottom:0; width:100%">
             <div style="position:absolute; width:100%; height:100%; text-align:center;bottom:0;">`
             + FormattedTextBox.LayoutString(fieldName + "Key") +
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index 4cf98472f..4e97b9401 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -15,6 +15,8 @@ import { ListField } from "../../fields/ListField";
 
 // @ts-ignore
 import * as typescriptlib from '!!raw-loader!./type_decls.d'
+import { Documents } from "../documents/Documents";
+import { Key } from "../../fields/Key";
 
 
 export interface ExecutableScript {
@@ -28,9 +30,9 @@ function Compile(script: string | undefined, diagnostics: Opt<any[]>, scope: { [
 
     let func: () => Opt<Field>;
     if (compiled && script) {
-        let fieldTypes = [Document, NumberField, TextField, ImageField, RichTextField, ListField];
-        let paramNames = ["KeyStore", ...fieldTypes.map(fn => fn.name)];
-        let params: any[] = [KeyStore, ...fieldTypes]
+        let fieldTypes = [Document, NumberField, TextField, ImageField, RichTextField, ListField, Key];
+        let paramNames = ["KeyStore", "Documents", ...fieldTypes.map(fn => fn.name)];
+        let params: any[] = [KeyStore, Documents, ...fieldTypes]
         for (let prop in scope) {
             if (prop === "this") {
                 continue;
diff --git a/src/client/util/type_decls.d b/src/client/util/type_decls.d
index dcf79285d..4f69053b1 100644
--- a/src/client/util/type_decls.d
+++ b/src/client/util/type_decls.d
@@ -174,6 +174,7 @@ declare class ListField<T> extends BasicField<T[]>{
     Copy(): Field;
 }
 declare class Key extends Field {
+    constructor(name:string);
     Name: string;
     TrySetValue(value: any): boolean;
     GetValue(): any;
@@ -220,3 +221,5 @@ declare const KeyStore: {
 
 // @ts-ignore
 declare const console: any;
+
+declare const Documents: any;
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index da9f7b392..8f7b4cfe7 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -83,6 +83,10 @@ export class CollectionFreeFormView extends CollectionViewBase {
             const [x, y] = this.getTransform().transformPoint(screenX, screenY);
             de.data.droppedDocument.SetNumber(KeyStore.X, x);
             de.data.droppedDocument.SetNumber(KeyStore.Y, y);
+            if (!de.data.droppedDocument.GetNumber(KeyStore.Width, 0)) {
+                de.data.droppedDocument.SetNumber(KeyStore.Width, 300);
+                de.data.droppedDocument.SetNumber(KeyStore.Height, 300);
+            }
             this.bringToFront(de.data.droppedDocument);
         }
     }
@@ -259,6 +263,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
         const lvalue = this.props.Document.GetT<ListField<Document>>(this.props.fieldKey, ListField);
         if (lvalue && lvalue != FieldWaiting) {
             return lvalue.Data.map(doc => {
+                if (!doc) return null;
                 var page = doc.GetNumber(KeyStore.Page, 0);
                 return (page != curPage && page != 0) ? (null) :
                     (<CollectionFreeFormDocumentView key={doc.Id} {...this.getDocumentViewProps(doc)} />);
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 8e0a38f05..7dd364449 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,6 +1,6 @@
 import React = require("react")
 import { library } from '@fortawesome/fontawesome-svg-core';
-import { faCog } from '@fortawesome/free-solid-svg-icons';
+import { faCog, faPlus } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable, trace, untracked } from "mobx";
 import { observer } from "mobx-react";
@@ -8,7 +8,7 @@ import Measure from "react-measure";
 import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table";
 import "react-table/react-table.css";
 import { Document } from "../../../fields/Document";
-import { Field, Opt } from "../../../fields/Field";
+import { Field, Opt, FieldWaiting } from "../../../fields/Field";
 import { Key } from "../../../fields/Key";
 import { KeyStore } from "../../../fields/KeyStore";
 import { ListField } from "../../../fields/ListField";
@@ -24,6 +24,7 @@ import { FieldView, FieldViewProps } from "../nodes/FieldView";
 import "./CollectionSchemaView.scss";
 import { CollectionView, COLLECTION_BORDER_WIDTH } from "./CollectionView";
 import { CollectionViewBase } from "./CollectionViewBase";
+import { TextField } from "../../../fields/TextField";
 
 
 // bcz: need to add drag and drop of rows and columns.  This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
@@ -104,11 +105,11 @@ export class CollectionSchemaView extends CollectionViewBase {
             return false;
         }
         return (
-            <div className="collectionSchemaView-cellContents" onPointerDown={onItemDown} style={{ height: "36px" }} key={props.doc.Id} ref={reference}>
+            <div className="collectionSchemaView-cellContents" onPointerDown={onItemDown} style={{ height: "56px" }} key={props.doc.Id} ref={reference}>
                 <EditableView
                     display={"inline"}
                     contents={contents}
-                    height={36}
+                    height={56}
                     GetValue={() => {
                         let field = props.doc.Get(props.fieldKey);
                         if (field && field instanceof Field) {
@@ -249,23 +250,48 @@ export class CollectionSchemaView extends CollectionViewBase {
         }
     }
 
+    @action
+    addColumn = () => {
+        this.columns.push(new Key(this.newKeyName));
+        this.newKeyName = "";
+    }
+
+    @observable
+    newKeyName: string = "";
+
+    @action
+    newKeyChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+        this.newKeyName = e.currentTarget.value;
+    }
+
     @observable _optionsActivated: number = 0;
     @action
     OptionsMenuDown = (e: React.PointerEvent) => {
         this._optionsActivated++;
     }
+
+    @observable previewScript: string = "this";
+    @action
+    onPreviewScriptChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+        this.previewScript = e.currentTarget.value;
+    }
+
     render() {
         library.add(faCog);
+        library.add(faPlus);
         const columns = this.columns;
         const children = this.props.Document.GetList<Document>(this.props.fieldKey, []);
         const selected = children.length > this._selectedIndex ? children[this._selectedIndex] : undefined;
         //all the keys/columns that will be displayed in the schema
         const allKeys = this.findAllDocumentKeys;
+        let doc: any = selected ? selected.Get(new Key(this.previewScript)) : undefined;
+
+        // let doc = CompileScript(this.previewScript, { this: selected }, true)();
         let content = this._selectedIndex == -1 || !selected ? (null) : (
             <Measure onResize={this.setScaling}>
                 {({ measureRef }) =>
                     <div className="collectionSchemaView-content" ref={measureRef}>
-                        <DocumentView Document={selected}
+                        {doc instanceof Document ? <DocumentView Document={doc}
                             AddDocument={this.props.addDocument} RemoveDocument={this.props.removeDocument}
                             isTopMost={false}
                             SelectOnLoad={false}
@@ -275,7 +301,9 @@ export class CollectionSchemaView extends CollectionViewBase {
                             PanelHeight={this.getPanelHeight}
                             ContainingCollectionView={this.props.CollectionView}
                             focus={this.focusDocument}
-                        />
+                        /> : null}
+                        <input value={this.previewScript} onChange={this.onPreviewScriptChange}
+                            style={{ position: 'absolute', bottom: '0px' }} />
                     </div>
                 }
             </Measure>
@@ -297,6 +325,8 @@ export class CollectionSchemaView extends CollectionViewBase {
                             return (<KeyToggle checked={allKeys[item]} key={item} keyId={item} toggle={this.toggleKey} />)
                         })}
                     </ul>
+                    <input value={this.newKeyName} onChange={this.newKeyChange} />
+                    <button onClick={this.addColumn}><FontAwesomeIcon style={{ color: "white" }} icon="plus" size="lg" /></button>
                 </div>
             </div>
             }>
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index f33007196..7d903899d 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -17,6 +17,7 @@ import { NumberField } from "../../../fields/NumberField";
 import { DocumentManager } from "../../util/DocumentManager";
 import request = require("request");
 import { ServerUtils } from "../../../server/ServerUtil";
+import { Server } from "../../Server";
 
 export interface CollectionViewProps {
     fieldKey: Key;
@@ -59,17 +60,20 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
         let email = CurrentUserUtils.email;
         if (id && email) {
             let textInfo: [string, string] = [id, email];
-            doc.GetOrCreateAsync<ListField<CursorEntry>>(KeyStore.Cursors, ListField, field => {
-                let cursors = field.Data;
-                if (cursors.length > 0 && (ind = cursors.findIndex(entry => entry.Data[0][0] === id)) > -1) {
-                    cursors[ind].Data[1] = position;
-                } else {
-                    let entry = new TupleField<[string, string], [number, number]>([textInfo, position]);
-                    cursors.push(entry);
+            doc.GetTAsync(KeyStore.Prototype, Document).then(proto => {
+                if (!proto) {
+                    return;
                 }
+                proto.GetOrCreateAsync<ListField<CursorEntry>>(KeyStore.Cursors, ListField, action((field: ListField<CursorEntry>) => {
+                    let cursors = field.Data;
+                    if (cursors.length > 0 && (ind = cursors.findIndex(entry => entry.Data[0][0] === id)) > -1) {
+                        cursors[ind].Data[1] = position;
+                    } else {
+                        let entry = new TupleField<[string, string], [number, number]>([textInfo, position]);
+                        cursors.push(entry);
+                    }
+                }))
             })
-
-
         }
     }
 
@@ -111,6 +115,21 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
             ctor = Documents.PdfDocument;
         }
         if (type.indexOf("html") !== -1) {
+            if (path.includes('localhost')) {
+                let s = path.split('/');
+                let id = s[s.length - 1];
+                Server.GetField(id).then(field => {
+                    if (field instanceof Document) {
+                        let alias = field.CreateAlias();
+                        alias.SetNumber(KeyStore.X, options.x || 0);
+                        alias.SetNumber(KeyStore.Y, options.y || 0);
+                        alias.SetNumber(KeyStore.Width, options.width || 300);
+                        alias.SetNumber(KeyStore.Height, options.height || options.width || 300);
+                        this.props.addDocument(alias, false);
+                    }
+                })
+                return undefined;
+            }
             ctor = Documents.WebDocument;
             options = { height: options.width, ...options, };
         }
@@ -130,7 +149,7 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
         e.stopPropagation()
         e.preventDefault()
 
-        if (html && html.indexOf("<img") != 0) {
+        if (html && html.indexOf("<img") != 0 && !html.startsWith("<a")) {
             console.log("not good");
             let htmlDoc = Documents.HtmlDocument(html, { ...options, width: 300, height: 300 });
             htmlDoc.SetText(KeyStore.DocumentText, text);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index cfe67c8fe..55aa1ccab 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -18,6 +18,7 @@ import { ContextMenu } from "../ContextMenu";
 import { DocumentContentsView } from "./DocumentContentsView";
 import "./DocumentView.scss";
 import React = require("react");
+import { ServerUtils } from "../../../server/ServerUtil";
 
 
 export interface DocumentViewProps {
@@ -283,6 +284,12 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         ContextMenu.Instance.addItem({ description: "Fields", event: this.fieldsClicked })
         ContextMenu.Instance.addItem({ description: "Center", event: () => this.props.focus(this.props.Document) })
         ContextMenu.Instance.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document) })
+        ContextMenu.Instance.addItem({
+            description: "Copy URL",
+            event: () => {
+                Utils.CopyText(ServerUtils.prepend("/doc/" + this.props.Document.Id));
+            }
+        });
         ContextMenu.Instance.addItem({
             description: "Copy ID",
             event: () => {
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index f6343c631..4e83ec7b9 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -16,6 +16,9 @@ import { VideoBox } from "./VideoBox";
 import { AudioBox } from "./AudioBox";
 import { AudioField } from "../../../fields/AudioField";
 import { ListField } from "../../../fields/ListField";
+import { DocumentContentsView } from "./DocumentContentsView";
+import { Transform } from "../../util/Transform";
+import { KeyStore } from "../../../fields/KeyStore";
 
 
 //
@@ -65,7 +68,20 @@ export class FieldView extends React.Component<FieldViewProps> {
             return <AudioBox {...this.props} />
         }
         else if (field instanceof Document) {
-            return <div>{field.Title}</div>
+            return (<DocumentContentsView Document={field}
+                AddDocument={undefined}
+                RemoveDocument={undefined}
+                ScreenToLocalTransform={() => Transform.Identity}
+                ContentScaling={() => 1}
+                PanelWidth={() => 100}
+                PanelHeight={() => 100}
+                isTopMost={true}
+                SelectOnLoad={false}
+                focus={() => { }}
+                isSelected={() => false}
+                select={() => false}
+                layoutKey={KeyStore.Layout}
+                ContainingCollectionView={undefined} />)
         }
         else if (field instanceof ListField) {
             return (<div>
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index ba9bd9566..30fa1342e 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -167,6 +167,8 @@ export class FormattedTextBox extends React.Component<FieldViewProps> {
             onKeyPress={this.onKeyPress}
             onPointerDown={this.onPointerDown}
             onContextMenu={this.specificContextMenu}
+            // tfs: do we need this event handler
+            onKeyDown={this.onKeyPress}
             onWheel={this.onPointerWheel}
             ref={this._ref} />)
     }
-- 
cgit v1.2.3-70-g09d2

