diff --git a/Assets/StreamingAssets/ScrollView_Server/build/Drop_facts.js b/Assets/StreamingAssets/ScrollView_Server/build/Drop_facts.js
new file mode 100644
index 0000000000000000000000000000000000000000..a13b81fa51437747279f0e372a1320e2c46eda53
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/build/Drop_facts.js
@@ -0,0 +1,126 @@
+"use strict";
+/**
+ * @typedef point
+ * @type {object}
+ * @property {number} x
+ * @property {number} y
+ * @property {number} z
+ */
+/**
+ * @typedef {Object} fact
+ * @property {string} id Fact id
+ * @property {string} s_type Fact type
+ * @property {string} label used in unity
+ * @property {string | null} _CustomLabel Custom label
+ * @property {boolean} hasCustomLabel
+ * @property {number} labelId
+ */
+/**
+ * @property {Point} point
+ * @property {Point} normal
+ * @property {string} s_type
+ * @property {string} label
+ * @property {string|null} _CustomLabel
+ * @property {boolean} hasCustomLabel
+ * @property {number} labelId
+ */
+var assignment;
+/** @param {DragEvent} event  */
+function dropHandler(event) {
+    // ignore 
+    if (event.dataTransfer === null
+        || event.target === null
+        || !(event.target instanceof HTMLElement)) {
+        console.log("Ignored illegal DragEvent");
+        return;
+    }
+    event.preventDefault();
+    console.log("dropHandler", event);
+    const data = event.dataTransfer.getData("application/json");
+    //const data = event.dataTransfer.getData("text/plain")
+    console.log(`Dropped data: '${event.dataTransfer.types}'`, event.dataTransfer.types);
+    const fact = JSON.parse(data);
+    console.warn(`Dropped Fact '${fact.label}':`, fact);
+    const target = event.target;
+    if (target.dataset.allowedTypes !== undefined) {
+        //const allowedTypesStr = element.dataset["allowed-types"]
+        const allowedTypesStr = target.dataset.allowedTypes;
+        const allowedTypes = allowedTypesStr.split(" ");
+        if (!allowedTypes.includes(fact.type)) {
+            console.warn(`The drop target is of type '${fact.type}' is not a member of the allowed types: ${allowedTypesStr}`);
+            return;
+        }
+    }
+    //element.fact = fact
+    target.dataset.factId = fact.uri;
+    target.dispatchEvent(new CustomEvent("FactAssigned", { detail: fact }));
+    // Mathmind belongs into Unity. 
+    // const mathMind = document.querySelector('#math-mind-canvas')
+    // if(mathMind instanceof HTMLCanvasElement)
+    // {
+    //     if (fact instanceof Point_Fact) {
+    //         mathMind.dispatchEvent(new CustomEvent("PointAssigned", {detail: fact}))
+    //         }
+    // }
+}
+/** @param {MouseEvent} event  */
+function clickHandler(event) {
+    // ignore 
+    if (event.target == null
+        || !(event.target instanceof HTMLElement)) {
+        console.warn("Ignored illegal DragEvent");
+        return;
+    }
+    event.preventDefault();
+    console.log("clickHandler");
+    console.log("clickHandler", event);
+    const target = event.target;
+    switch (event.button) {
+        case 0:
+            console.log("Left button clicked");
+            target.dataset.factId = undefined;
+            target.dispatchEvent(new Event("factUnassigned"));
+            break;
+        case 1:
+            console.log("Middle button clicked");
+            break;
+        case 2:
+            console.log("Right button clicked");
+            if (target.dataset.slotId) {
+                getHint(target.dataset.slotId);
+            }
+            break;
+        default:
+            console.log("Unknown button clicked");
+    }
+}
+/*
+* register the drag event listeners
+*/
+//document.addEventListener("dragstart", ev => printHandler(ev, "DragStartEvent"))
+//document.addEventListener("dragenter", ev => printHandler(ev, "DragEnterEvent"))
+//document.addEventListener("drag", ev => printHandler(ev, "DragEvent"))
+document.addEventListener("dragover", ev => ev.preventDefault());
+//document.addEventListener("dragover", ev => printPreventDefaultHandler(ev, "DragOverEvent"))
+//document.addEventListener("dragleave", ev => printHandler(ev, "DragLeaveEvent"))
+//document.addEventListener("dragend", ev => printHandler(ev, "DragEndEvent"))
+// select all dropzones and add drop event listeners
+//let dropZones = document.querySelectorAll('[dropzone="copy"]')
+//dropZones.forEach( dropZone => dropZone.addEventListener("drop", ev => dropHandler(ev, "DropEvent")) )
+/** select all dropzones and add drop event listeners */
+function addDropZoneEventListeners() {
+    console.log("addDropZoneEventListeners");
+    document.querySelectorAll('[dropzone="copy"]')
+        .forEach(dropZone => {
+        if (dropZone instanceof HTMLElement) {
+            dropZone.removeEventListener("drop", dropHandler);
+            dropZone.removeEventListener("click", clickHandler);
+            dropZone.removeEventListener("contextmenu", clickHandler);
+            //dropZone.addEventListener("dragover", ev => ev.preventDefault())
+            dropZone.addEventListener("drop", dropHandler);
+            dropZone.addEventListener("click", clickHandler);
+            dropZone.addEventListener("contextmenu", clickHandler);
+        }
+    });
+}
+//addDropZoneEventListeners()
diff --git a/Assets/StreamingAssets/ScrollView_Server/build/Facts.js b/Assets/StreamingAssets/ScrollView_Server/build/Facts.js
new file mode 100644
index 0000000000000000000000000000000000000000..70f7fa2b0ee02f12aecc3c5ba4f186559212b2e0
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/build/Facts.js
@@ -0,0 +1,176 @@
+"use strict";
+/**
+ * A fact without any value known to us
+ */
+class Simple_Fact {
+    constructor(label, uri, representations, type) {
+        this.label = label;
+        this.uri = uri;
+        this.representations = representations instanceof MathMLElement ? { "default": representations } : representations;
+        this.type = type ? type : "none";
+    }
+    show_value(hint) {
+        if (hint in this.representations)
+            return this.representations[hint];
+        else
+            return this.representations["default"];
+    }
+}
+/**
+ * A simple point (x,y,z) in 3D space
+ */
+class Point_Fact {
+    /**
+     * @param x The x component of (x,y,z)
+     * @param y The y component of (x,y,z)
+     * @param z The z component of (x,y,z)
+     */
+    constructor(label, uri, x, y, z) {
+        this.label = label;
+        this.uri = uri;
+        this.x = x;
+        this.y = y;
+        this.z = z;
+        this.type = "Point_Fact";
+    }
+    /**
+     * @returns "({@link x},{@link y},{@link z})" as MathML \<mrow\> element
+     */
+    show_value() {
+        const show = document.createElement("mrow");
+        show.appendChild(document.createElement("mo"))
+            .textContent = "(";
+        show.appendChild(document.createElement("mn"))
+            .textContent = this.x.toString();
+        show.appendChild(document.createElement("mo"))
+            .textContent = ",";
+        show.appendChild(document.createElement("mn"))
+            .textContent = this.y.toString();
+        show.appendChild(document.createElement("mo"))
+            .textContent = ",";
+        show.appendChild(document.createElement("mn"))
+            .textContent = this.y.toString();
+        show.appendChild(document.createElement("mo"))
+            .textContent = ")";
+        return show;
+    }
+}
+class Angle_Fact {
+    constructor(label, uri, p1, p2, p3, angel, is_right_angle, _representations) {
+        this.label = label;
+        this.uri = uri;
+        this.p1 = p1;
+        this.p2 = p2;
+        this.p3 = p3;
+        this.angel = angel;
+        this.is_right_angle = is_right_angle;
+        this.type = "Angle_Fact";
+        if (_representations !== undefined) {
+            this.representations = _representations;
+        }
+        else {
+            this.representations = {};
+            let show = document.createElement("mn");
+            show.textContent = `${this.angel / 180 * Math.PI}`;
+            this.representations.radiants = show;
+            show = document.createElement("mrow");
+            show.appendChild(document.createElement("mi"))
+                .textContent = `${this.angel}`;
+            show.appendChild(document.createElement("mo"))
+                .textContent = "°";
+            this.representations;
+        }
+    }
+    show_value(hint) {
+        const show = document.createElement("mrow");
+        switch (hint) {
+            case "radiants":
+            case "Radiants":
+            case "rad":
+                return this.representations.radiants;
+            case "degrees": // Degrees is the default
+            case "Degrees":
+            case "deg":
+            default:
+                show.appendChild(document.createElement("mi"))
+                    .textContent = `${this.angel}`;
+                show.appendChild(document.createElement("mo"))
+                    .textContent = "°";
+                break;
+        }
+        return show;
+    }
+}
+class Line_Fact {
+    constructor(label, uri, p1, p2, _representations) {
+        this.label = label;
+        this.uri = uri;
+        this.p1 = p1;
+        this.p2 = p2;
+        this.type = "Line_Fact";
+        if (_representations !== undefined) {
+            this.representations = _representations;
+        }
+        else {
+            this.representations = {};
+            let show = document.createElement("mrow");
+            show.appendChild(document.createElement("mtext"))
+                .textContent = `The Line though `;
+            show.appendChild(this.p1.label);
+            show.appendChild(document.createElement("mtext"))
+                .textContent = ` and `;
+            show.appendChild(this.p1.label);
+            this.representations["Semantic Definition"] = show;
+            show = document.createElement("mrow");
+        }
+    }
+    /**
+     *
+     * @param hint possible values:
+     * - "Semantic Definition" : "Line through {@link p1} and {@link p2}"
+     *
+     * !!Not implemented yet!!
+     * - "Point vector"
+     * - "Parametric equation"
+     * - "Hesse normal form"
+     * @returns Dependent on {@link hint}
+     */
+    show_value(hint) {
+        switch (hint) {
+            case "Point vector":
+            case "Parametric equation":
+            case "Hesse normal form":
+                throw new Error("Not implemented.");
+                break;
+            case "Semantic Definition":
+            default:
+                return this.representations["Semantic Definition"];
+        }
+    }
+}
+class LineSegment_Fact extends Line_Fact {
+    constructor(label, uri, p1, p2, length, _representations) {
+        super(label, uri, p1, p2, _representations);
+        this.label = label;
+        this.uri = uri;
+        this.p1 = p1;
+        this.p2 = p2;
+        this.length = length;
+        this.type = "LineSegment_Fact";
+    }
+    show_value() {
+        const show = document.createElement("mn");
+        show.textContent = this.length.toString();
+        return show;
+    }
+}
+class Ray_Fact extends Line_Fact {
+    constructor(label, uri, p1, p2, _representations) {
+        super(label, uri, p1, p2, _representations);
+        this.label = label;
+        this.uri = uri;
+        this.p1 = p1;
+        this.p2 = p2;
+        this.type = "Ray_Fact";
+    }
+}
diff --git a/Assets/StreamingAssets/ScrollView_Server/build/Math_Mind.js b/Assets/StreamingAssets/ScrollView_Server/build/Math_Mind.js
new file mode 100644
index 0000000000000000000000000000000000000000..3006bd8d54ce31769fc9848b87298836b2a225bb
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/build/Math_Mind.js
@@ -0,0 +1,77 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    var desc = Object.getOwnPropertyDescriptor(m, k);
+    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+      desc = { enumerable: true, get: function() { return m[k]; } };
+    }
+    Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+    Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+    o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || (function () {
+    var ownKeys = function(o) {
+        ownKeys = Object.getOwnPropertyNames || function (o) {
+            var ar = [];
+            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
+            return ar;
+        };
+        return ownKeys(o);
+    };
+    return function (mod) {
+        if (mod && mod.__esModule) return mod;
+        var result = {};
+        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
+        __setModuleDefault(result, mod);
+        return result;
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+const THREE = __importStar(require("three"));
+const OrbitControls_js_1 = require("three/addons/controls/OrbitControls.js");
+$(function () {
+    const scene = new THREE.Scene();
+    const camera = new THREE.PerspectiveCamera(75, 4 / 3, 0.1, 1000);
+    const renderer = new THREE.WebGLRenderer({
+        canvas: document.querySelector('#math-mind-canvas')
+    });
+    // The canvas is initially hidden, in case the three.js import fails
+    // If we reach this code, it obviously didn't
+    renderer.domElement.removeAttribute("hidden");
+    const controls = new OrbitControls_js_1.OrbitControls(camera, renderer.domElement);
+    const gridHelper = new THREE.GridHelper(20, 20);
+    scene.add(gridHelper);
+    camera.position.set(10, 5, -15);
+    controls.update();
+    function animate() {
+        renderer.render(scene, camera);
+        controls.update();
+    }
+    renderer.setAnimationLoop(animate);
+    const pointGeo = new THREE.SphereGeometry(0.1);
+    const material = new THREE.MeshBasicMaterial({ color: 0xf0f0f0 });
+    /**
+     *
+     * @param {Point_Fact} point
+     */
+    function addPointFact(point) {
+        console.log(point);
+        const point_visual = new THREE.Mesh(pointGeo, material);
+        scene.add(point_visual);
+        point_visual.position.set(point.x, point.y, point.z);
+        console.log("added point to Math_Mind", point);
+    }
+    document.querySelector('#math-mind-canvas').addEventListener("PointAssigned", function (event) {
+        //console.log(event)
+        addPointFact(event.detail);
+    });
+    addPointFact({ x: 5.8, y: 0.1, z: -10.5 });
+    addPointFact({ x: 5.8, y: 6.2, z: -10.5 });
+    addPointFact({ x: 8.0, y: 0.1, z: -6.6 });
+});
diff --git a/Assets/StreamingAssets/ScrollView_Server/build/SetScrollContent.js b/Assets/StreamingAssets/ScrollView_Server/build/SetScrollContent.js
new file mode 100644
index 0000000000000000000000000000000000000000..06388b36d6b4b176a015b7407e3d7d97aba3718b
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/build/SetScrollContent.js
@@ -0,0 +1,106 @@
+"use strict";
+/**
+ * A MMT..whatever. Somewhere between the first and second "meta-" MMT had to leave common nomenclature behind
+ * @typedef {{kind : string, uri: string}} MMTReference
+ */
+/**
+ * Facts, as they are send by MMT. Not *quite* the same format as Unity uses \*sigh\*, and everything has shortened names to avoid five additional letters \*double sigh\*
+ * @typedef {Object} MMTFact
+ * @property {MMTReference} ref the reference MMT uses to identify this fact
+ * @property {string} label the human readable lable to display this fact.
+ * @property {?any} df the definition of the Fact. May be null for {@link MMTScroll.requiredFacts}
+ * @property {?MMTReference} tp the MMT type of this fact
+ * @property {string} kind since a Fact is a MMTThingy, they also have a {@link MMTReference.kind}
+ */
+/**
+ * A Slot is an interface that can stand in for either
+ * - a {@link Fact}, or
+ * - the {@link Backend_Object} used to define the {@link Scroll} (in the backend)
+ *
+ * depending on what is needed.
+ *
+ * If all Slots of a {@link Scroll} are assigned, it can compute its {@link Scroll.acquiredFacts}.
+ */
+class Slot {
+    /**
+     * @param default_label The default label of the Slot. Fallback if no Fact is assigned.
+     * @param uri The uri of the Slot
+     * @param type The expected type of the assigned Fact
+     * @param assignedFact The Fact assigned to this Slot (may not exist yet)
+     */
+    constructor(default_label, uri, type, assignedFact) {
+        this.default_label = default_label;
+        this.uri = uri;
+        this.type = type;
+        this.assignedFact = assignedFact;
+        this.assignedFact = assignedFact;
+    }
+    /**
+     * The MathML element to display when this Slot is referenced.
+     *
+     * This is either the label of the {@link assignedFact}, or {@link default_label} if the former doesn't exist.
+     */
+    get label() {
+        if (this.assignedFact) {
+            return this.assignedFact.label;
+        }
+        else {
+            return this.default_label;
+        }
+    }
+}
+/**
+ * A Scroll, as it is implemented in the backend.
+ *
+ * Can do fancy stuff elsewhere, here we only want display its {@link description} and (possibly) {@link depiction}.
+ * Both will reference the {@link slots}, and need dynamic adaption to the {@link Fact}s assigned to them.
+ * The {@link acquiredFacts} referenced do not change, but they are semantically important and deserve special treatment.
+ */
+class Scroll {
+    constructor(label, uri, slots, acquiredFacts, description, depiction) {
+        this.label = label;
+        this.uri = uri;
+        this.slots = slots;
+        this.acquiredFacts = acquiredFacts;
+        this.description = description;
+        this.depiction = depiction;
+        this.type = "Scroll";
+    }
+    /** TODO */
+    static fromString(scrollString) {
+        throw new Error("Not implemented.");
+    }
+}
+let currentScrollRef = ""; // ref of the scroll currently displayed 
+function RenderScroll() {
+    const dataSource = document.querySelector("#Unity-Data-Interface");
+    if (!(dataSource instanceof HTMLElement)
+        || dataSource === null
+        || dataSource.dataset.scrollDynamic === undefined) {
+        console.error("No Scroll found in the Unity-Data-Interface");
+        return;
+    }
+    const scroll = Scroll.fromString(dataSource.dataset.scrollDynamic);
+    //console.log(scroll.requiredFacts);
+    const scrollContainer = document.querySelector("#scrollContainer");
+    // replace the description if the scroll changed, otherwise only its content needs update
+    // if (scroll.ref != currentScrollRef) {
+    //     currentScrollRef = scroll.ref;
+    //     scrollContainer.innerHTML = scroll.description;
+    // }
+    // go through the facts in the scroll, show their labels, add dropzones and limit the allowed types
+    scroll.slots.forEach(slot => {
+        $(`[data-slot-id='${slot.uri}']`)
+            .html(slot.label)
+            .attr("dropzone", "copy");
+    });
+    // acquired facts only need updated labels
+    scroll.acquiredFacts.forEach(fact => {
+        $(`[data-solution-id='${fact.uri}']`)
+            .html(fact.label);
+    });
+    console.log(scroll.label + 'Scroll rendered');
+}
+$(function () {
+    RenderScroll();
+});
diff --git a/Assets/StreamingAssets/ScrollView_Server/package-lock.json b/Assets/StreamingAssets/ScrollView_Server/package-lock.json
index a37e8cd1efcb7572ee1b24a3e8955cea2c59f1f6..7a4bb050c945dcad2cbb026146e0a539fd45fb63 100644
--- a/Assets/StreamingAssets/ScrollView_Server/package-lock.json
+++ b/Assets/StreamingAssets/ScrollView_Server/package-lock.json
@@ -8,6 +8,8 @@
         "three": "^0.172.0"
       },
       "devDependencies": {
+        "@types/jquery": "^3.5.32",
+        "typescript": "^5.7.3",
         "vite": "^6.0.11"
       }
     },
@@ -709,6 +711,23 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/@types/jquery": {
+      "version": "3.5.32",
+      "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.32.tgz",
+      "integrity": "sha512-b9Xbf4CkMqS02YH8zACqN1xzdxc3cO735Qe5AbSUFmyOiaWAbcpqh9Wna+Uk0vgACvoQHpWDg2rGdHkYPLmCiQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/sizzle": "*"
+      }
+    },
+    "node_modules/@types/sizzle": {
+      "version": "2.3.9",
+      "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz",
+      "integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/esbuild": {
       "version": "0.24.2",
       "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
@@ -875,6 +894,20 @@
       "integrity": "sha512-6HMgMlzU97MsV7D/tY8Va38b83kz8YJX+BefKjspMNAv0Vx6dxMogHOrnRl/sbMIs3BPUKijPqDqJ/+UwJbIow==",
       "license": "MIT"
     },
+    "node_modules/typescript": {
+      "version": "5.7.3",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
+      "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=14.17"
+      }
+    },
     "node_modules/vite": {
       "version": "6.0.11",
       "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.11.tgz",
diff --git a/Assets/StreamingAssets/ScrollView_Server/package.json b/Assets/StreamingAssets/ScrollView_Server/package.json
index 309ce56cd82a12d242f2afd773aa3e3075b2d203..ce640e63ce28dd67350999dedb682d0e6745ba26 100644
--- a/Assets/StreamingAssets/ScrollView_Server/package.json
+++ b/Assets/StreamingAssets/ScrollView_Server/package.json
@@ -3,6 +3,8 @@
     "three": "^0.172.0"
   },
   "devDependencies": {
+    "@types/jquery": "^3.5.32",
+    "typescript": "^5.7.3",
     "vite": "^6.0.11"
   }
 }
diff --git a/Assets/StreamingAssets/ScrollView_Server/scrollView.html b/Assets/StreamingAssets/ScrollView_Server/scrollView.html
index 3139c46b9506186b5b6c6d191a8b5e80f011c02b..4cc7c05e66dab451ea8458f41ccc9008b14f5023 100644
--- a/Assets/StreamingAssets/ScrollView_Server/scrollView.html
+++ b/Assets/StreamingAssets/ScrollView_Server/scrollView.html
@@ -6,8 +6,16 @@
     <title>Scroll View</title>
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <style>
+        [data-allowed-types="PointFact"] * {
+            color: #0000ff
+        }
+        
+        [data-allowed-types="LineFact"] * {
+            color: #008000
+        }
+
         [dropzone] {
-            background-color: grey;
+            /* background-color: grey; */
             margin: 1px;
             border-width: 1px;
             border-style: dashed;
@@ -41,7 +49,7 @@
             background-color: red;
         }
     </style>
-    <script src="jquery-3.7.1.slim.min.js"></script> 
+    <script src="jquery-3.7.1.slim.min.js"></script>
 </head>
 
 <body>
@@ -51,81 +59,91 @@
     <div id="scrollContainer">
         <scroll-description title='DefaultScroll' alt='No scroll loaded yet'>
             <div>No scroll selected yet.</div>
-            <span>Given a triangle</span>
-            <math>
-                <mi>&xutri;<!-- △ --></mi>
-                <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?A"></mi>
-                <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?B"></mi>
-                <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"></mi>
-            </math>
-            <span>right-angled at</span>
-            <math>
-                <!--<mi>&angrtvbd;</mi>--><!-- ⦝ -->
-                <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC">
-                </mi>
-            </math>,<br />
-            <span>the opposite side has length</span>
-            <math>
-                <mi data-solution-id="http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA"></mi>
-                <mo>&equals;</mo>
-                <mrow>
-                    <mi>tan</mi>
-                    <!--<mo>&#8289;</mo>-->
-                    <mo>(</mo>
-                    <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB"></mi>
-                    <mo>)</mo>
-                </mrow>
-                <mo>&#8290;</mo>
-                <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC"></mi>
-            </math>
-            <span>.</span>
             <div>
-                <svg width='50mm' height='45mm' viewBox='35 0 90 70' version='1.1' id='triangle'
+                Given a triangle
+                <math>
+                    <mrow>
+                        <mi>&xutri;<!-- △ --></mi>
+                        <slot data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?A" />
+                        <slot data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?B" />
+                        <slot data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?C" />
+                    </mrow>
+                </math>
+                right-angled at
+                <math>
+                    <!--<mi>&angrtvbd;</mi>--><!-- ⦝ -->
+                    <mrow>
+                        <slot
+                            data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC" />
+                    </mrow>
+                </math>,<br />
+                the opposite side has length
+                <math>
+                    <mi data-solution-id="http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA">
+                    </mi>
+                    <mo>&equals;</mo>
+                    <mrow>
+                        <mi>tan</mi>
+                        <!--<mo>&#8289;</mo>-->
+                        <mo>(</mo>
+                        <slot data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB"/>
+                        <mo>)</mo>
+                    <mo>&times;</mo>
+                    <slot data-slot-id="http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC"/>
+                    </mrow>
+                </math>.
+            </div>
+            <div>
+                <svg width='8cm' height='8cmm' viewBox='-25 -25 300 300' version='1.1' id='triangle'
                     xmlns='http://www.w3.org/2000/svg' xmlns:svg='http://www.w3.org/2000/svg'>
-                    <g id='shape'>
-                        <path
-                            style='fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1'
-                            d='M 42.871972,64.67128 H 84.290656 V 7.6297578 Z' id='triangle' />
-                        <path id='angleABC'
-                            style='fill:none;stroke:#000000;stroke-width:0.265;stroke-dasharray:none;stroke-opacity:1'
-                            d='m 46.024276,60.304806 a 5.3589964,5.3589964 0 0 1 2.252109,4.366474 h -5.358996 z' />
+                    <g id='shape'
+                        style='fill:none;stroke:#000000;stroke-linecap:butt;stroke-width:1;stroke-linejoin:miter;stroke-opacity:1'>
+                        <path d='M 0,250 H 200 V 0 Z' id='triangle' />
+                        <path id='angleABC' d='M 0,250 l 15.6,-19.5 a 25 25 0 0 1 9.4,19.5 z' />
+                        <!-- M [corner] l [25*cos()],[-25*sin()] a 25 25 0 0 1 [25-25*cos()],[25*sin()]-->
                         <g id='angleBCA'>
-                            <path
-                                style='fill:none;stroke:#000000;stroke-width:0.264999;stroke-dasharray:none;stroke-opacity:1'
-                                id='rightAngle'
-                                d='m 78.972396,64.665062 a 5.3308268,5.3308268 0 0 1 5.330827,-5.330827 v 5.330827 z' />
-                            <circle
-                                style='fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264999;stroke-dasharray:none;stroke-opacity:1'
-                                id='rightAngleDot' cx='82.081886' cy='62.813831' r='0.32113415' />
+                            <path id='rightAngle' d='M 200,250 v -25 a 25,25 0 0 0 -25,25 z' />
+                            <circle style='fill:#000000;fill-opacity:1;stroke:none' id='rightAngleDot' cx='190' cy='240'
+                                r='1.5' />
+                            <!-- Corner - (40,40); 40 = 15/sqrt(2) + epsilon -->
                         </g>
                     </g>
-                    <g id='labels'
-                        style='font-size:4.23333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583'>
-                        <text xml:space='preserve' x='39.242592' y='67.117035' id='pointB' style='fill:#0000ff'
-                            data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem?B'>${lverb B}</text>
-                        <text xml:space='preserve' x='85.100548' y='68.080437' id='pointC' style='fill:#0000ff'
-                            data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem?C'>${lverb C}</text>
-                        <text xml:space='preserve' x='84.650963' y='6.551136' id='pointA' style='fill:#0000ff'
-                            data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem?A'>${lverb A}</text>
-                        <text xml:space='preserve' x='48.234348' y='62.492699' id='angleAtB' style='fill:#ffcc00'
-                            data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB'>${lverb
-                            angleB}</text>
-                        <text xml:space='preserve' x='71.548683' y='60.951256' id='rightAngleAtC' style='fill:#ffcc00'
-                            data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC'>${lverb
-                            rightAngleC}</text>
-                        <text xml:space='preserve' x='59.409813' y='68.273117' id='distanceBC' style='fill:#008000'
-                            data-slot-id='http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC'>${lverb
-                            distanceBC}</text>
-                        <text xml:space='preserve' x='84.972092' y='35.260529' id='solutionCA' style='fill:#008000'
-                            data-solution-id='http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA'>${lverb
-                            deducedLineCA}</text>
+                    <g id='labels' style='line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;'>
+                        <foreignObject id='pointB' x='200' y='-25' width="25" height="25">
+                            <math xmlns="http://www.w3.org/1998/Math/MathML"
+                                data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?A" />
+                        </foreignObject>
+                        <foreignObject id='pointB' x='-25' y='250' width="25" height="25">
+                            <math xmlns="http://www.w3.org/1998/Math/MathML"
+                                data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?B" />
+                        </foreignObject>
+                        <foreignObject id='pointB' x='200' y='250' width="25" height="25">
+                            <math xmlns="http://www.w3.org/1998/Math/MathML"
+                                data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?C" />
+                        </foreignObject>
+                        <foreignObject id='pointB' x='30' y='225' width="50" height="25">
+                            <math xmlns="http://www.w3.org/1998/Math/MathML"
+                            data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB' />
+                        </foreignObject>
+                        <foreignObject id='pointB' x='145' y='225' width="50" height="25">
+                            <math xmlns="http://www.w3.org/1998/Math/MathML"
+                            data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC' />
+                        </foreignObject>
+                        <foreignObject id='pointB' x='100' y='250' width="50" height="25">
+                            <math xmlns="http://www.w3.org/1998/Math/MathML"
+                            data-slot-id='http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC' />
+                        </foreignObject>
+                        <foreignObject id='pointB' x='205' y='120' width="50" height="25">
+                            <math xmlns="http://www.w3.org/1998/Math/MathML" style='color:#008000'
+                            data-solution-id='http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA' />
+                        </foreignObject>
                     </g>
                 </svg>
             </div>
         </scroll-description>
     </div>
     <button type="button" title="Apply the scroll" onclick="applyScroll('')">Apply</button><br>
-    <p>You can right click on yellow slots to get a hint.</p>
+    <p>You can right-click on yellow slots to get a hint.</p>
 
     <script id="load-other-scripts">
         /** 
@@ -142,14 +160,14 @@
             head.appendChild(script);
         }
 
-        loadScript("./scroll_interaction/Drop_facts.js")
-        loadScript("./scroll_interaction/SetScrollContent.js")
+        loadScript("./build/Drop_facts.js")
+        loadScript("./build/SetScrollContent.js")
         //loadScript("./scroll_interaction/webgl-demo.js")
 
     </script>
-    <script src="./scroll_interaction/Math_Mind.js" type="module"></script>
+    <script src="./build/Math_Mind.js" type="module"></script>
     <data id="Unity-Data-Interface" hidden
-        data-assignments='{&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem?A&quot;:{&quot;Item1&quot;:&quot;(C)&quot;,&quot;Item2&quot;:&quot;http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact310&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem?B&quot;:{&quot;Item1&quot;:&quot;(B)&quot;,&quot;Item2&quot;:&quot;http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact309&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem?C&quot;:{&quot;Item1&quot;:&quot;C&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC&quot;:{&quot;Item1&quot;:&quot;⊾C&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC&quot;:{&quot;Item1&quot;:&quot;BC&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB&quot;:{&quot;Item1&quot;:&quot;∠ABC&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA&quot;:{&quot;Item1&quot;:&quot;CA&quot;,&quot;Item2&quot;:&quot;&quot;}}' 
+        data-assignments='{&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem?A&quot;:{&quot;Item1&quot;:&quot;(C)&quot;,&quot;Item2&quot;:&quot;http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact310&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem?B&quot;:{&quot;Item1&quot;:&quot;(B)&quot;,&quot;Item2&quot;:&quot;http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact309&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem?C&quot;:{&quot;Item1&quot;:&quot;C&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC&quot;:{&quot;Item1&quot;:&quot;⊾C&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC&quot;:{&quot;Item1&quot;:&quot;BC&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB&quot;:{&quot;Item1&quot;:&quot;∠ABC&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA&quot;:{&quot;Item1&quot;:&quot;CA&quot;,&quot;Item2&quot;:&quot;&quot;}}'
         data-scroll-dynamic='{
             "ref": "http://mathhub.info/FrameIT/frameworld?OppositeLen",
             "label": "OppositeLen",
diff --git a/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Drop_facts.js b/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Drop_facts.js
deleted file mode 100644
index 7a11e5f07266ccc0e97e1daf21e665bfbc3a8c41..0000000000000000000000000000000000000000
--- a/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Drop_facts.js
+++ /dev/null
@@ -1,217 +0,0 @@
-/**
- * @typedef point
- * @type {object}
- * @property {number} x
- * @property {number} y
- * @property {number} z
- */
-
-/**
- * @typedef {Object} fact
- * @property {string} id Fact id
- * @property {string} s_type Fact type
- * @property {string} label used in unity
- * @property {string | null} _CustomLabel Custom label
- * @property {boolean} hasCustomLabel
- * @property {number} labelId
- */
-
-/**
- * @property {Point} point
- * @property {Point} normal
- * @property {string} s_type
- * @property {string} label
- * @property {string|null} _CustomLabel
- * @property {boolean} hasCustomLabel
- * @property {number} labelId
- */
-
-var assignment;
-
-class Fact {
-    /** @property {string} id Fact id */
-    id = ""
-    /** @property {string} s_type Fact type */
-    s_type = ""
-    /** @property {string} label used in unity */
-    label = ""
-    /** @property {string | null} _CustomLabel Custom label */
-    _CustomLabel = null
-    /** @property {boolean} hasCustomLabel */
-    hasCustomLabel = false
-    /** @property {number} labelId */
-    labelId = 0
-}
-
-class Point {
-    /** @property {number} x */
-    x = 0
-    /** @property {number} y */
-    y = 0
-    /** @property {number} z */
-    z = 0
-}
-/**
-s_type: PointFact,
-label: A,
-_CustomLabel: null,
-hasCustomLabel: false,
-labelId: 0,
-point: {x: -1.66086578, y: -0.00494432449, z: -2.17682648},
-normal: {x: 0, y: 1, z: 0}
-*/
-class PointFact extends Fact {
-    s_type = "PointFact";
-    /** @property {Point} point */
-    point = new Point()
-    /** @property {Point} normal */
-    normal = new Point()
-}
-
-/**
- * pid1: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact252,
-pid2: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact254,
-pid3: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact256,
-s_type: AngleFact,
-label: ∠BDF,
-_CustomLabel: null,
-is_right_angle: false,
-hasCustomLabel: false,
-labelId: 0
-*/
-class AngleFact extends Fact {
-    s_type = "AngleFact";
-    pid1 = "";
-    pid2 = "";
-    pid3 = "";
-    is_right_angle = false;
-}
-
-/**
- * s_type: LineFact,
-pid1: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact255,
-pid2: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact256,
-dir: [object Object],
-label: [EF],
-_CustomLabel: null,
-hasCustomLabel: false,
-labelId: 0
-*/
-class LineFact extends Fact {
-    s_type = "LineFact";
-    pid1 = "";
-    pid2 = "";
-    dir = new Point();
-}
-
-/**
- * s_type: RayFact,
-pid1: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact256,
-pid2: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact252,
-dir: [object Object],
-label: FB,
-_CustomLabel: null,
-hasCustomLabel: false,
-labelId: 0
-*/
-class RayFact extends Fact {
-    s_type = "RayFact";
-    pid1 = "";
-    pid2 = "";
-    dir = new Point();
-}
-
-
-
-/** @param {DragEvent} event  */
-function dropHandler(event) {
-    event.preventDefault()
-    console.log("dropHandler", event)
-
-    const data = event.dataTransfer.getData("application/json")
-    //const data = event.dataTransfer.getData("text/plain")
-    console.log(`Dropped data: '${event.dataTransfer.types}'`, event.dataTransfer.types)
-
-    /** @type {fact} */
-    const fact = JSON.parse(data)
-    console.warn(`Dropped Fact '${fact.label}':`, fact)
-
-    /** @type {HTMLElement} */
-    const element = event.target
-
-    if (element.hasAttribute("data-allowed-types")) {
-    //const allowedTypesStr = element.dataset["allowed-types"]
-    const allowedTypesStr = element.getAttribute("data-allowed-types")
-    const allowedTypes = allowedTypesStr.split(" ")
-
-    if (!allowedTypes.includes(fact.s_type)) {
-        console.warn(`The drop target data-type '${fact.s_type}' is not a member of the allowed types '${allowedTypesStr}'`)
-        return
-    }
-    }
-
-    element.innerHTML = fact.label
-    element.fact = fact
-    element.dataset.factId = fact.id
-
-    const mathMind = document.querySelector('#math-mind-canvas')
-    if (fact.s_type == "PointFact") {
-        mathMind.dispatchEvent(new CustomEvent("PointAssigned", {detail: fact.point}))
-    }
-    
-}
-
-/** @param {MouseEvent} event  */
-function clickHandler(event) {
-    event.preventDefault()
-    console.log("clickHandler")
-    console.log("clickHandler", event)
-    switch (event.button) {
-    case 0:
-        console.log("Left button clicked")
-        event.target.fact = null
-        event.target.dataset.factId = null
-        element.dispatchEvent(new Event("factUnassigned"))
-        break
-    case 1:
-        console.log("Middle button clicked")
-        break
-    case 2:
-        console.log("Right button clicked")
-        getHint(event.target.dataset.slotId)
-        break
-    default:
-        console.log("Unknown button clicked")
-    }
-}
-
-/*
-* register the drag event listeners
-*/
-//document.addEventListener("dragstart", ev => printHandler(ev, "DragStartEvent"))
-//document.addEventListener("dragenter", ev => printHandler(ev, "DragEnterEvent"))
-//document.addEventListener("drag", ev => printHandler(ev, "DragEvent"))
-document.addEventListener("dragover", ev => ev.preventDefault())
-//document.addEventListener("dragover", ev => printPreventDefaultHandler(ev, "DragOverEvent"))
-//document.addEventListener("dragleave", ev => printHandler(ev, "DragLeaveEvent"))
-//document.addEventListener("dragend", ev => printHandler(ev, "DragEndEvent"))
-
-// select all dropzones and add drop event listeners
-//let dropZones = document.querySelectorAll('[dropzone="copy"]')
-//dropZones.forEach( dropZone => dropZone.addEventListener("drop", ev => dropHandler(ev, "DropEvent")) )
-
-/** select all dropzones and add drop event listeners */
-function addDropZoneEventListeners() {
-    console.log("addDropZoneEventListeners")
-    document.querySelectorAll('[dropzone="copy"]')
-    .forEach( dropZone => {
-        dropZone.removeEventListener("drop", dropHandler)
-        dropZone.removeEventListener("click", clickHandler)
-        dropZone.removeEventListener("contextmenu", clickHandler)
-        //dropZone.addEventListener("dragover", ev => ev.preventDefault())
-        dropZone.addEventListener("drop", dropHandler)
-        dropZone.addEventListener("click", clickHandler)
-        dropZone.addEventListener("contextmenu", clickHandler)
-    })
-}
-//addDropZoneEventListeners()
diff --git a/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/SetScrollContent.js b/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/SetScrollContent.js
deleted file mode 100644
index f75dec691c2232ecd75d2c33679a75a799f375f5..0000000000000000000000000000000000000000
--- a/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/SetScrollContent.js
+++ /dev/null
@@ -1,67 +0,0 @@
-
-/**
- * A MMT..whatever. Somewhere between the first and second "meta-" MMT had to leave common nomenclature behind
- * @typedef {{kind : string, uri: string}} MMTReference
- */
-/**
- * Facts, as they are send by MMT. Not *quite* the same format as Unity uses \*sigh\*, and everything has shortened names to avoid five additional letters \*double sigh\*
- * @typedef {Object} MMTFact
- * @property {MMTReference} ref the reference MMT uses to identify this fact 
- * @property {string} label the human readable lable to display this fact. 
- * @property {?any} df the definition of the Fact. May be null for {@link MMTScroll.requiredFacts}
- * @property {?MMTReference} tp the MMT type of this fact
- * @property {string} kind since a Fact is a MMTThingy, they also have a {@link MMTReference.kind}
- */
-/**
- * @typedef {Object} MMTScroll
- * @property {string} ref The MMT URI
- * @property {string} label The human-readable name
- * @property {string} description The description to be rendered here
- * @property {MMTFact[]} requiredFacts List of all facts required to apply the scroll. If the scroll has been partially applied these Facts may be the assigned ones
- * @property {MMTFact[]} acquiredFacts List of all facts that will be acquired when applying the scroll
- * @property {string} name Unity artifact; The URI again
- * @property {?string} path Unity artifact; will always be null
- */
-
-let currentScrollRef = "" // ref of the scroll currently displayed 
-
-function RenderScroll() {
-    /** @type {MMTScroll} */
-    const scroll = JSON.parse(document.querySelector("#Unity-Data-Interface").dataset.scrollDynamic);
-    //console.log(scroll.requiredFacts);
-    const scrollContainer = document.querySelector("#scrollContainer");
-
-    // replace the description if the scroll changed, otherwise only its content needs update
-    if (scroll.ref != currentScrollRef) {
-        currentScrollRef = scroll.ref;
-        scrollContainer.innerHTML = scroll.description;
-    }
-
-    // go through the facts in the scroll, show their labels, add dropzones and limit the allowed types
-    scroll.requiredFacts.forEach(fact => {
-        $("[data-slot-id='" + fact.ref.uri + "']")
-            .text(fact.label)
-            .attr("dropzone", "copy")
-            .attr("data-allowed-types", function (_, _) {
-                // Since MMT types are extremely expressive, many things can go wrong here. Luckily this means the fact is certainly not a PointFact, and we are done.
-                try {
-                    if (fact.tp.uri = "http://mathhub.info/MitM/core/geometry?3DGeometry?point") { return "PointFact"; }
-
-                }
-                catch (err) { }
-            })
-        //.attr("data-fact-id", fact.df == null ? "" : fact.df.ref.uri)
-    })
-
-    // acquired facts only need updated labels
-    scroll.acquiredFacts.forEach(fact => {
-        $("[data-solution-id='" + fact.ref.uri + "']")
-            .text(fact.label)
-    })
-    console.log(scroll.label + 'Scroll rendered')
-}
-
-
-$(function () {
-    RenderScroll()
-});
\ No newline at end of file
diff --git a/Assets/StreamingAssets/ScrollView_Server/src.meta b/Assets/StreamingAssets/ScrollView_Server/src.meta
new file mode 100644
index 0000000000000000000000000000000000000000..14683f2aaea9f8265604f3a026b5f002b595e716
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/src.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: edf292450f4b7c84596506c809e0d82a
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/StreamingAssets/ScrollView_Server/src/Drop_facts.ts b/Assets/StreamingAssets/ScrollView_Server/src/Drop_facts.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bd2c9e73753060eccc3f1d2387802fd646e1aa63
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/src/Drop_facts.ts
@@ -0,0 +1,143 @@
+/**
+ * @typedef point
+ * @type {object}
+ * @property {number} x
+ * @property {number} y
+ * @property {number} z
+ */
+
+/**
+ * @typedef {Object} fact
+ * @property {string} id Fact id
+ * @property {string} s_type Fact type
+ * @property {string} label used in unity
+ * @property {string | null} _CustomLabel Custom label
+ * @property {boolean} hasCustomLabel
+ * @property {number} labelId
+ */
+
+/**
+ * @property {Point} point
+ * @property {Point} normal
+ * @property {string} s_type
+ * @property {string} label
+ * @property {string|null} _CustomLabel
+ * @property {boolean} hasCustomLabel
+ * @property {number} labelId
+ */
+
+var assignment;
+
+/** @param {DragEvent} event  */
+function dropHandler(event: DragEvent) {
+    // ignore 
+    if (event.dataTransfer === null
+        || event.target === null
+        || !(event.target instanceof HTMLElement)) {
+        console.log("Ignored illegal DragEvent")
+        return
+    }
+    event.preventDefault()
+    console.log("dropHandler", event)
+
+    const data = event.dataTransfer.getData("application/json")
+    //const data = event.dataTransfer.getData("text/plain")
+    console.log(`Dropped data: '${event.dataTransfer.types}'`, event.dataTransfer.types)
+
+    const fact: Fact = JSON.parse(data)
+    console.warn(`Dropped Fact '${fact.label}':`, fact)
+
+    const target: HTMLElement = event.target
+
+    if (target.dataset.allowedTypes !== undefined) {
+        //const allowedTypesStr = element.dataset["allowed-types"]
+        const allowedTypesStr = target.dataset.allowedTypes
+        const allowedTypes = allowedTypesStr.split(" ")
+
+        if (!allowedTypes.includes(fact.type)) {
+            console.warn(`The drop target is of type '${fact.type}' is not a member of the allowed types: ${allowedTypesStr}`)
+            return
+        }
+    }
+
+    //element.fact = fact
+    target.dataset.factId = fact.uri
+    target.dispatchEvent(new CustomEvent("FactAssigned", {detail: fact}))
+
+    // Mathmind belongs into Unity. 
+    // const mathMind = document.querySelector('#math-mind-canvas')
+    // if(mathMind instanceof HTMLCanvasElement)
+    // {
+    //     if (fact instanceof Point_Fact) {
+    //         mathMind.dispatchEvent(new CustomEvent("PointAssigned", {detail: fact}))
+    //         }
+    // }
+
+}
+
+/** @param {MouseEvent} event  */
+function clickHandler(event: MouseEvent) {
+    // ignore 
+    if (event.target == null
+        || !(event.target instanceof HTMLElement)) {
+        console.warn("Ignored illegal DragEvent")
+        return
+    }
+    event.preventDefault()
+    console.log("clickHandler")
+    console.log("clickHandler", event)
+    const target: HTMLElement = event.target
+    switch (event.button) {
+        case 0:
+            console.log("Left button clicked")
+            target.dataset.factId = undefined
+            target.dispatchEvent(new Event("factUnassigned"))
+            break
+        case 1:
+            console.log("Middle button clicked")
+            break
+        case 2:
+            console.log("Right button clicked")
+            if (target.dataset.slotId) {
+                getHint(target.dataset.slotId)
+            }
+            break
+        default:
+            console.log("Unknown button clicked")
+    }
+}
+
+/*
+* register the drag event listeners
+*/
+//document.addEventListener("dragstart", ev => printHandler(ev, "DragStartEvent"))
+//document.addEventListener("dragenter", ev => printHandler(ev, "DragEnterEvent"))
+//document.addEventListener("drag", ev => printHandler(ev, "DragEvent"))
+document.addEventListener("dragover", ev => ev.preventDefault())
+//document.addEventListener("dragover", ev => printPreventDefaultHandler(ev, "DragOverEvent"))
+//document.addEventListener("dragleave", ev => printHandler(ev, "DragLeaveEvent"))
+//document.addEventListener("dragend", ev => printHandler(ev, "DragEndEvent"))
+
+// select all dropzones and add drop event listeners
+//let dropZones = document.querySelectorAll('[dropzone="copy"]')
+//dropZones.forEach( dropZone => dropZone.addEventListener("drop", ev => dropHandler(ev, "DropEvent")) )
+
+/** select all dropzones and add drop event listeners */
+function addDropZoneEventListeners() {
+    console.log("addDropZoneEventListeners")
+    document.querySelectorAll('[dropzone="copy"]')
+        .forEach(dropZone => {
+            if (dropZone instanceof HTMLElement) {
+                dropZone.removeEventListener("drop", dropHandler)
+                dropZone.removeEventListener("click", clickHandler)
+                dropZone.removeEventListener("contextmenu", clickHandler)
+                //dropZone.addEventListener("dragover", ev => ev.preventDefault())
+                dropZone.addEventListener("drop", dropHandler)
+                dropZone.addEventListener("click", clickHandler)
+                dropZone.addEventListener("contextmenu", clickHandler)
+            }
+        })
+}
+
+declare function getHint(slotId: string): void;
+//addDropZoneEventListeners()
diff --git a/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/SetScrollContent.js.meta b/Assets/StreamingAssets/ScrollView_Server/src/Drop_facts.ts.meta
similarity index 74%
rename from Assets/StreamingAssets/ScrollView_Server/scroll_interaction/SetScrollContent.js.meta
rename to Assets/StreamingAssets/ScrollView_Server/src/Drop_facts.ts.meta
index cedf0ac5485748bf9bf7e22d808882c9b48c5327..2e10f46a5751809d3f26aa256e14bb9f9c68e8b1 100644
--- a/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/SetScrollContent.js.meta
+++ b/Assets/StreamingAssets/ScrollView_Server/src/Drop_facts.ts.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 215e6162e17215b4a9118b3db2f4944f
+guid: 02e8201cb481fff4db877a448f700956
 DefaultImporter:
   externalObjects: {}
   userData: 
diff --git a/Assets/StreamingAssets/ScrollView_Server/src/Facts.ts b/Assets/StreamingAssets/ScrollView_Server/src/Facts.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2817647512ce31f8317270a8fe2f6dba462f0044
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/src/Facts.ts
@@ -0,0 +1,243 @@
+/**
+ * The Attributes all things have in the Backend. 
+ * 
+ * UPL calls "things you can define" Objects, but they are somewhat closer to ts types. (Except for {@link Fact}s)
+ */
+interface Backend_Object{
+    /** The MathML element to display when this object is referenced */
+    readonly label: MathMLElement
+    /** A unique identifier of the object. Unlike label, this only needs to be machine-readable, not pretty */
+    readonly uri: string
+    /** The type of the object */
+    readonly type: string
+}
+
+/**
+ * A Fact is an instance (witness) of a `Backend_Object`, and as such it also has a value. 
+ * @see representations Internal storage of possible MathML elements to display to the user when the value is referenced. For access using {@link show_value} is preferable, as it can have a default value and alike.
+ * @see show_value(hint?) The MathML element to display to the user when the value is referenced. Abstract, because it is 100% reliant on the specific type of fact. Hint allows to choose between different representation formats (e.g. degrees or radiants)
+ */
+interface Fact extends Backend_Object{
+    /**
+     * Internal storage of possible MathML elements to display to the user when the value is referenced. Highly dependent on the type of fact. 
+     * More often than not there are multiple representations, and hint allows to choose between them. 
+     * 
+     * For access use {@link show_value}, as it can have a default value and alike.
+     */
+    readonly representations?: {[hint: string]: MathMLElement}
+    
+    
+    /**
+     * The MathML element to display to the user when the value is referenced.
+     * 
+     * @param hint An optional hint, if there is more than one option for showing the value
+     * 
+     * @returns A MathML element to display, when the value referenced
+     */
+    show_value(hint?: string): MathMLElement;
+}
+
+/**
+ * A fact without any value known to us
+ */
+class Simple_Fact implements Fact{
+    representations: { [hint: string]: MathMLElement }
+    type: string 
+    constructor(
+        readonly label: MathMLElement,
+        readonly uri: string,
+        representations: MathMLElement | { [hint: string]: MathMLElement },
+        type?: string,
+    ) {
+        this.representations = representations instanceof MathMLElement ? { "default": representations } : representations
+        this.type = type ? type  : "none"
+    }
+    
+    show_value(hint: string): MathMLElement {
+        if (hint in this.representations)
+            return this.representations[hint]
+        else
+            return this.representations["default"]
+    }
+    
+}
+
+/**
+ * A simple point (x,y,z) in 3D space
+ */
+class Point_Fact implements Fact{
+    readonly type: string = "Point_Fact"
+    /**
+     * @param x The x component of (x,y,z)
+     * @param y The y component of (x,y,z)
+     * @param z The z component of (x,y,z)
+     */
+    constructor(
+        readonly label: MathMLElement,
+        readonly uri: string,
+        readonly x: number,
+        readonly y: number,
+        readonly z: number,
+    ) { }
+
+    /**
+     * @returns "({@link x},{@link y},{@link z})" as MathML \<mrow\> element
+     */
+    show_value(): MathMLElement {const show: MathMLElement = document.createElement("mrow")
+        show.appendChild(document.createElement("mo"))
+            .textContent = "("
+        show.appendChild(document.createElement("mn"))
+            .textContent = this.x.toString()
+        show.appendChild(document.createElement("mo"))
+            .textContent = ","
+        show.appendChild(document.createElement("mn"))
+            .textContent = this.y.toString()
+        show.appendChild(document.createElement("mo"))
+            .textContent = ","
+        show.appendChild(document.createElement("mn"))
+            .textContent = this.y.toString()
+        show.appendChild(document.createElement("mo"))
+            .textContent = ")"
+        return show
+    }
+}
+
+class Angle_Fact implements Fact{
+    readonly representations: {[hint: string]: MathMLElement}
+    readonly type: string  = "Angle_Fact"
+    constructor(
+        readonly label: MathMLElement,
+        readonly uri: string,
+        readonly p1: Point_Fact,
+        readonly p2: Point_Fact,
+        readonly p3: Point_Fact,
+        readonly angel: number,
+        readonly is_right_angle: boolean,
+        _representations?: {[hint: string]: MathMLElement}
+    ){
+        if (_representations !== undefined) {
+            this.representations = _representations
+        }
+        else {
+            this.representations = {}
+            let show: MathMLElement = document.createElement("mn")
+            show.textContent = `${this.angel / 180 * Math.PI}`
+            this.representations.radiants = show 
+            
+            show = document.createElement("mrow")
+            show.appendChild(document.createElement("mi"))
+                .textContent = `${this.angel}`
+            show.appendChild(document.createElement("mo"))
+                .textContent = "°"
+            this.representations
+        }
+    }
+    
+    show_value(hint?: string): MathMLElement {
+        const show: MathMLElement = document.createElement("mrow")
+        switch (hint) {
+            case "radiants":
+            case "Radiants":
+            case "rad":
+                return this.representations.radiants
+
+            case "degrees": // Degrees is the default
+            case "Degrees":
+            case "deg":
+            default:
+                show.appendChild(document.createElement("mi"))
+                    .textContent = `${this.angel}`
+                show.appendChild(document.createElement("mo"))
+                    .textContent = "°"
+                break;
+        }
+        return show
+    }
+}
+
+class Line_Fact implements Fact{
+    readonly representations: { [hint: string]: MathMLElement; };
+    readonly type : string = "Line_Fact"
+    constructor(
+        readonly label: MathMLElement,
+        readonly uri: string,
+        readonly p1: Point_Fact,
+        readonly p2: Point_Fact,
+        _representations?: {[hint: string]: MathMLElement}
+    ){
+        if (_representations !== undefined) {
+            this.representations = _representations
+        }
+        else {
+            this.representations = {}
+            let show: MathMLElement = document.createElement("mrow")
+            show.appendChild(document.createElement("mtext"))
+                .textContent = `The Line though `
+            show.appendChild(this.p1.label)
+            show.appendChild(document.createElement("mtext"))
+                .textContent = ` and `
+            show.appendChild(this.p1.label)
+            this.representations["Semantic Definition"] = show
+
+            show = document.createElement("mrow")
+        }
+    }
+
+    /**
+     * 
+     * @param hint possible values: 
+     * - "Semantic Definition" : "Line through {@link p1} and {@link p2}"
+     * 
+     * !!Not implemented yet!!
+     * - "Point vector"
+     * - "Parametric equation"
+     * - "Hesse normal form"
+     * @returns Dependent on {@link hint}
+     */
+    show_value(hint?: string): MathMLElement {
+        switch (hint) {
+            case "Point vector":
+            case "Parametric equation":
+            case "Hesse normal form":
+                throw new Error("Not implemented.");
+                break;
+            
+            case "Semantic Definition":
+            default:
+                return this.representations["Semantic Definition"]
+        }
+    }
+}
+
+class LineSegment_Fact extends Line_Fact{
+    readonly type: string = "LineSegment_Fact"
+    constructor(
+        readonly label: MathMLElement,
+        readonly uri: string,
+        readonly p1: Point_Fact,
+        readonly p2: Point_Fact,
+        readonly length: number,
+        _representations?: {[hint: string]: MathMLElement}
+    ) {
+        super(label,uri,p1,p2,_representations)
+    }
+    
+    show_value(): MathMLElement {
+        const show: MathMLElement = document.createElement("mn")
+        show.textContent = this.length.toString()
+        return show
+    }
+}
+
+class Ray_Fact extends Line_Fact {
+    readonly type: string = "Ray_Fact"
+    constructor(
+        readonly label: MathMLElement,
+        readonly uri: string,
+        readonly p1: Point_Fact,
+        readonly p2: Point_Fact,
+        _representations?: {[hint: string]: MathMLElement}
+    ) {
+        super(label,uri,p1,p2,_representations)
+    }
+}
diff --git a/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Drop_facts.js.meta b/Assets/StreamingAssets/ScrollView_Server/src/Facts.ts.meta
similarity index 74%
rename from Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Drop_facts.js.meta
rename to Assets/StreamingAssets/ScrollView_Server/src/Facts.ts.meta
index a98621e25b5e9222e2c1e3eb7062f07299840cc4..b06217e34ba608cdc587e79140c929087c77af17 100644
--- a/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Drop_facts.js.meta
+++ b/Assets/StreamingAssets/ScrollView_Server/src/Facts.ts.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 817c254809af43848b2648523bd2fa70
+guid: ec80f551fb37027428052e03d1e006f7
 DefaultImporter:
   externalObjects: {}
   userData: 
diff --git a/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Math_Mind.js b/Assets/StreamingAssets/ScrollView_Server/src/Math_Mind.js
similarity index 82%
rename from Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Math_Mind.js
rename to Assets/StreamingAssets/ScrollView_Server/src/Math_Mind.js
index fb3352ce21473c5d1a53827064fbfb403a86d611..53a0fdf4f56b7ec5b654afb9420ffd4153588f6f 100644
--- a/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Math_Mind.js
+++ b/Assets/StreamingAssets/ScrollView_Server/src/Math_Mind.js
@@ -12,10 +12,10 @@ $(function () {
     // If we reach this code, it obviously didn't
     renderer.domElement.removeAttribute("hidden");
     const controls = new OrbitControls(camera, renderer.domElement);
-    const gridHelper = new THREE.GridHelper();
+    const gridHelper = new THREE.GridHelper(20,20);
     scene.add(gridHelper);
 
-    camera.position.set(5, -5, 5);
+    camera.position.set(10, 5, -15);
     controls.update();
 
     function animate() {
@@ -29,7 +29,7 @@ $(function () {
     const material = new THREE.MeshBasicMaterial({ color: 0xf0f0f0 });
     /**
      * 
-     * @param {PointFact} point 
+     * @param {Point_Fact} point 
      */
     function addPointFact(point) {
         console.log(point)
@@ -40,7 +40,11 @@ $(function () {
     }
 
     document.querySelector('#math-mind-canvas').addEventListener("PointAssigned", function (event) {
-        console.log(event)
+        //console.log(event)
         addPointFact(event.detail)
     })
+
+    addPointFact({x: 5.8, y: 0.1, z: -10.5 })
+    addPointFact({x: 5.8, y: 6.2, z: -10.5 })
+    addPointFact({x: 8.0, y: 0.1, z: -6.6  })
 });
diff --git a/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Math_Mind.js.meta b/Assets/StreamingAssets/ScrollView_Server/src/Math_Mind.js.meta
similarity index 100%
rename from Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Math_Mind.js.meta
rename to Assets/StreamingAssets/ScrollView_Server/src/Math_Mind.js.meta
diff --git a/Assets/StreamingAssets/ScrollView_Server/src/SetScrollContent.ts b/Assets/StreamingAssets/ScrollView_Server/src/SetScrollContent.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fa608daf3898743a400df8ecd3cb8ccaa09e5258
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/src/SetScrollContent.ts
@@ -0,0 +1,119 @@
+
+/**
+ * A MMT..whatever. Somewhere between the first and second "meta-" MMT had to leave common nomenclature behind
+ * @typedef {{kind : string, uri: string}} MMTReference
+ */
+/**
+ * Facts, as they are send by MMT. Not *quite* the same format as Unity uses \*sigh\*, and everything has shortened names to avoid five additional letters \*double sigh\*
+ * @typedef {Object} MMTFact
+ * @property {MMTReference} ref the reference MMT uses to identify this fact 
+ * @property {string} label the human readable lable to display this fact. 
+ * @property {?any} df the definition of the Fact. May be null for {@link MMTScroll.requiredFacts}
+ * @property {?MMTReference} tp the MMT type of this fact
+ * @property {string} kind since a Fact is a MMTThingy, they also have a {@link MMTReference.kind}
+ */
+
+/**
+ * A Slot is an interface that can stand in for either
+ * - a {@link Fact}, or
+ * - the {@link Backend_Object} used to define the {@link Scroll} (in the backend)
+ * 
+ * depending on what is needed.
+ * 
+ * If all Slots of a {@link Scroll} are assigned, it can compute its {@link Scroll.acquiredFacts}.
+ */
+class Slot implements Backend_Object{
+    /**
+     * @param default_label The default label of the Slot. Fallback if no Fact is assigned.
+     * @param uri The uri of the Slot
+     * @param type The expected type of the assigned Fact
+     * @param assignedFact The Fact assigned to this Slot (may not exist yet)
+     */
+    constructor(
+        readonly default_label: MathMLElement,
+        readonly uri: string,
+        readonly type: string,
+        public assignedFact?: Fact
+    ) { this.assignedFact = assignedFact }
+    
+    /** 
+     * The MathML element to display when this Slot is referenced.
+     * 
+     * This is either the label of the {@link assignedFact}, or {@link default_label} if the former doesn't exist.
+     */
+    get label(): MathMLElement{
+        if (this.assignedFact) {
+            return this.assignedFact.label
+        }
+        else {
+            return this.default_label
+        }
+    }
+    
+}
+
+/**
+ * A Scroll, as it is implemented in the backend.
+ * 
+ * Can do fancy stuff elsewhere, here we only want display its {@link description} and (possibly) {@link depiction}.
+ * Both will reference the {@link slots}, and need dynamic adaption to the {@link Fact}s assigned to them.
+ * The {@link acquiredFacts} referenced do not change, but they are semantically important and deserve special treatment.
+ */
+class Scroll implements Backend_Object{
+    readonly type: string = "Scroll"
+    constructor(
+        readonly label: MathMLElement,
+        readonly uri: string,
+        readonly slots: Slot[],
+        readonly acquiredFacts: Backend_Object[],
+        readonly description: HTMLElement,
+        readonly depiction?: HTMLElement,
+    ) { }
+
+    /** TODO */
+    static fromString(scrollString: string): Scroll {
+        
+        throw new Error("Not implemented.");
+    }
+}
+
+let currentScrollRef = "" // ref of the scroll currently displayed 
+
+function RenderScroll() {
+    const dataSource = document.querySelector("#Unity-Data-Interface")
+    if (!(dataSource instanceof HTMLElement)
+        || dataSource === null
+        || dataSource.dataset.scrollDynamic === undefined
+    ) {
+        console.error("No Scroll found in the Unity-Data-Interface")
+        return
+    }
+    const scroll = Scroll.fromString(dataSource.dataset.scrollDynamic);
+    //console.log(scroll.requiredFacts);
+    const scrollContainer = document.querySelector("#scrollContainer");
+
+    // replace the description if the scroll changed, otherwise only its content needs update
+    // if (scroll.ref != currentScrollRef) {
+    //     currentScrollRef = scroll.ref;
+    //     scrollContainer.innerHTML = scroll.description;
+    // }
+
+    // go through the facts in the scroll, show their labels, add dropzones and limit the allowed types
+    scroll.slots.forEach(slot => {
+        $(`[data-slot-id='${slot.uri}']`)
+            .html(slot.label)
+            .attr("dropzone", "copy")
+    })
+
+    // acquired facts only need updated labels
+    scroll.acquiredFacts.forEach(fact => {
+        $(`[data-solution-id='${fact.uri}']`)
+            .html(fact.label)
+    })
+    console.log(scroll.label + 'Scroll rendered')
+}
+
+
+$(function () {
+    RenderScroll()
+});
\ No newline at end of file
diff --git a/Assets/StreamingAssets/ScrollView_Server/src/SetScrollContent.ts.meta b/Assets/StreamingAssets/ScrollView_Server/src/SetScrollContent.ts.meta
new file mode 100644
index 0000000000000000000000000000000000000000..03b4f8415f1dd3d790a0f3e247bd682bc559b912
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/src/SetScrollContent.ts.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 36e0063345b02594eb3949f8bd19e603
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/StreamingAssets/ScrollView_Server/tmp.json b/Assets/StreamingAssets/ScrollView_Server/tmp.json
new file mode 100644
index 0000000000000000000000000000000000000000..da1a3d86f2b3d26f27091af559533fbc310e095f
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/tmp.json
@@ -0,0 +1,334 @@
+{
+    "ref": "http://mathhub.info/FrameIT/frameworld?OppositeLen",
+    "label": "OppositeLen",
+    "description": "<scroll-description title=&#x27;OppositeLenScroll&#x27; alt=&#x27;Given a triangle △ABC right-angled at ⊾C, the opposite side has length CA = tan(∠ABC) ⋅ BC.&#x27;>     <span>Given a triangle</span>       <math>           <mi>&xutri;<!-- △ --></mi>           <mi data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem?A&#x27;></mi>           <mi data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem?B&#x27;></mi>           <mi data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem?C&#x27;></mi>       </math>       <span>right-angled at</span>       <math>           <!--<mi>&angrtvbd;</mi>--><!-- ⦝ -->           <mi data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC&#x27;></mi>       </math>,<br />       <span>the opposite side has length</span>       <math>           <mi data-solution-id=&#x27;http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA&#x27;></mi>           <mo>&equals;</mo>           <mrow>               <mi>tan</mi>               <!--<mo>&#8289;</mo>-->               <mo>(</mo>               <mi data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB&#x27;></mi>               <mo>)</mo>           </mrow>           <mo>&#8290;</mo>           <mi data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC&#x27;></mi>       </math>       <span>.</span>       <div>           <svg           width=&#x27;50mm&#x27;           height=&#x27;45mm&#x27;           viewBox=&#x27;35 0 90 70&#x27;           version=&#x27;1.1&#x27;           id=&#x27;triangle&#x27;           xmlns=&#x27;http://www.w3.org/2000/svg&#x27;           xmlns:svg=&#x27;http://www.w3.org/2000/svg&#x27;>           <g id=&#x27;shape&#x27;>               <path                   style=&#x27;fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1&#x27;                   d=&#x27;M 42.871972,64.67128 H 84.290656 V 7.6297578 Z&#x27;                   id=&#x27;triangle&#x27; />               <path                   id=&#x27;angleABC&#x27;                   style=&#x27;fill:none;stroke:#000000;stroke-width:0.265;stroke-dasharray:none;stroke-opacity:1&#x27;                   d=&#x27;m 46.024276,60.304806 a 5.3589964,5.3589964 0 0 1 2.252109,4.366474 h -5.358996 z&#x27; />               <g                   id=&#x27;angleBCA&#x27;>                   <path                       style=&#x27;fill:none;stroke:#000000;stroke-width:0.264999;stroke-dasharray:none;stroke-opacity:1&#x27;                       id=&#x27;rightAngle&#x27;                       d=&#x27;m 78.972396,64.665062 a 5.3308268,5.3308268 0 0 1 5.330827,-5.330827 v 5.330827 z&#x27; />                   <circle                       style=&#x27;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264999;stroke-dasharray:none;stroke-opacity:1&#x27;                       id=&#x27;rightAngleDot&#x27;                       cx=&#x27;82.081886&#x27;                       cy=&#x27;62.813831&#x27;                       r=&#x27;0.32113415&#x27; />               </g>           </g>           <g               id=&#x27;labels&#x27;               style=&#x27;font-size:4.23333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583&#x27;           >               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;39.242592&#x27;                   y=&#x27;67.117035&#x27;                   id=&#x27;pointB&#x27;                   style=&#x27;fill:#0000ff&#x27;                   data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem?B&#x27;>B</text>               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;85.100548&#x27;                   y=&#x27;68.080437&#x27;                   id=&#x27;pointC&#x27;                   style=&#x27;fill:#0000ff&#x27;                   data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem?C&#x27;>C</text>               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;84.650963&#x27;                   y=&#x27;6.551136&#x27;                   id=&#x27;pointA&#x27;                   style=&#x27;fill:#0000ff&#x27;                   data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem?A&#x27;>A</text>               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;48.234348&#x27;                   y=&#x27;62.492699&#x27;                   id=&#x27;angleAtB&#x27;                   style=&#x27;fill:#ffcc00&#x27;                   data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB&#x27;>∠ABC</text>               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;71.548683&#x27;                   y=&#x27;60.951256&#x27;                   id=&#x27;rightAngleAtC&#x27;                   style=&#x27;fill:#ffcc00&#x27;                   data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC&#x27;>⊾C</text>               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;59.409813&#x27;                   y=&#x27;68.273117&#x27;                   id=&#x27;distanceBC&#x27;                   style=&#x27;fill:#008000&#x27;                   data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC&#x27;>BC</text>               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;84.972092&#x27;                   y=&#x27;35.260529&#x27;                   id=&#x27;solutionCA&#x27;                   style=&#x27;fill:#008000&#x27;                   data-solution-id=&#x27;http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA&#x27;>CA</text>           </g>           </svg>       </div> </scroll-description>",
+    "requiredFacts": [
+        {
+            "tp": {
+                "kind": "OMS",
+                "uri": "http://mathhub.info/MitM/core/geometry?3DGeometry?point"
+            },
+            "df": null,
+            "ref": {
+                "kind": "OMS",
+                "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?A"
+            },
+            "kind": "general",
+            "label": "A"
+        },
+        {
+            "tp": {
+                "kind": "OMS",
+                "uri": "http://mathhub.info/MitM/core/geometry?3DGeometry?point"
+            },
+            "df": null,
+            "ref": {
+                "kind": "OMS",
+                "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?B"
+            },
+            "kind": "general",
+            "label": "B"
+        },
+        {
+            "tp": {
+                "kind": "OMS",
+                "uri": "http://mathhub.info/MitM/core/geometry?3DGeometry?point"
+            },
+            "df": null,
+            "ref": {
+                "kind": "OMS",
+                "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"
+            },
+            "kind": "general",
+            "label": "C"
+        },
+        {
+            "tp": {
+                "kind": "OMA",
+                "applicant": {
+                    "kind": "OMS",
+                    "uri": "http://mathhub.info/MitM/Foundation?Logic?ded"
+                },
+                "arguments": [
+                    {
+                        "kind": "OMA",
+                        "applicant": {
+                            "kind": "OMS",
+                            "uri": "http://mathhub.info/MitM/Foundation?Logic?eq"
+                        },
+                        "arguments": [
+                            {
+                                "kind": "OMS",
+                                "uri": "http://mathhub.info/MitM/Foundation?RealLiterals?real_lit"
+                            },
+                            {
+                                "kind": "OMA",
+                                "applicant": {
+                                    "kind": "OMS",
+                                    "uri": "http://mathhub.info/MitM/core/geometry?Geometry/Common?angle_between"
+                                },
+                                "arguments": [
+                                    {
+                                        "kind": "OMS",
+                                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?B"
+                                    },
+                                    {
+                                        "kind": "OMS",
+                                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"
+                                    },
+                                    {
+                                        "kind": "OMS",
+                                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?A"
+                                    }
+                                ]
+                            },
+                            {
+                                "kind": "OMLIT<Double>",
+                                "type": "http://mathhub.info/MitM/Foundation?RealLiterals?real_lit",
+                                "value": 90.0
+                            }
+                        ]
+                    }
+                ]
+            },
+            "df": null,
+            "ref": {
+                "kind": "OMS",
+                "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC"
+            },
+            "kind": "general",
+            "label": "⊾C"
+        },
+        {
+            "lhs": {
+                "kind": "OMA",
+                "applicant": {
+                    "kind": "OMS",
+                    "uri": "http://mathhub.info/MitM/core/geometry?Geometry/Common?metric"
+                },
+                "arguments": [
+                    {
+                        "kind": "OMS",
+                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?B"
+                    },
+                    {
+                        "kind": "OMS",
+                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"
+                    }
+                ]
+            },
+            "valueTp": {
+                "kind": "OMS",
+                "uri": "http://mathhub.info/MitM/Foundation?RealLiterals?real_lit"
+            },
+            "value": null,
+            "proof": null,
+            "ref": {
+                "kind": "OMS",
+                "uri": "http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC"
+            },
+            "kind": "veq",
+            "label": "BC"
+        },
+        {
+            "lhs": {
+                "kind": "OMA",
+                "applicant": {
+                    "kind": "OMS",
+                    "uri": "http://mathhub.info/MitM/core/geometry?Geometry/Common?angle_between"
+                },
+                "arguments": [
+                    {
+                        "kind": "OMS",
+                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?A"
+                    },
+                    {
+                        "kind": "OMS",
+                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?B"
+                    },
+                    {
+                        "kind": "OMS",
+                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"
+                    }
+                ]
+            },
+            "valueTp": {
+                "kind": "OMS",
+                "uri": "http://mathhub.info/MitM/Foundation?RealLiterals?real_lit"
+            },
+            "value": null,
+            "proof": null,
+            "ref": {
+                "kind": "OMS",
+                "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB"
+            },
+            "kind": "veq",
+            "label": "∠ABC"
+        }
+    ],
+    "acquiredFacts": [
+        {
+            "lhs": {
+                "kind": "OMA",
+                "applicant": {
+                    "kind": "OMS",
+                    "uri": "http://mathhub.info/MitM/core/geometry?Geometry/Common?metric"
+                },
+                "arguments": [
+                    {
+                        "kind": "OMS",
+                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"
+                    },
+                    {
+                        "kind": "OMS",
+                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?A"
+                    }
+                ]
+            },
+            "valueTp": {
+                "kind": "OMS",
+                "uri": "http://mathhub.info/MitM/Foundation?RealLiterals?real_lit"
+            },
+            "value": {
+                "kind": "OMA",
+                "applicant": {
+                    "kind": "OMS",
+                    "uri": "http://mathhub.info/MitM/core/arithmetics?RealArithmetics?multiplication"
+                },
+                "arguments": [
+                    {
+                        "kind": "OMA",
+                        "applicant": {
+                            "kind": "OMS",
+                            "uri": "http://mathhub.info/MitM/Foundation?Trigonometry?tan"
+                        },
+                        "arguments": [
+                            {
+                                "kind": "OMA",
+                                "applicant": {
+                                    "kind": "OMS",
+                                    "uri": "http://gl.mathhub.info/MMT/LFX/Sigma?Symbols?Projl"
+                                },
+                                "arguments": [
+                                    {
+                                        "kind": "OMS",
+                                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB"
+                                    }
+                                ]
+                            }
+                        ]
+                    },
+                    {
+                        "kind": "OMA",
+                        "applicant": {
+                            "kind": "OMS",
+                            "uri": "http://gl.mathhub.info/MMT/LFX/Sigma?Symbols?Projl"
+                        },
+                        "arguments": [
+                            {
+                                "kind": "OMS",
+                                "uri": "http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC"
+                            }
+                        ]
+                    }
+                ]
+            },
+            "proof": {
+                "kind": "OMA",
+                "applicant": {
+                    "kind": "OMS",
+                    "uri": "http://mathhub.info/MitM/Foundation?InformalProofs?proofsketch"
+                },
+                "arguments": [
+                    {
+                        "kind": "OMA",
+                        "applicant": {
+                            "kind": "OMS",
+                            "uri": "http://mathhub.info/MitM/Foundation?Logic?eq"
+                        },
+                        "arguments": [
+                            {
+                                "kind": "OMS",
+                                "uri": "http://mathhub.info/MitM/Foundation?RealLiterals?real_lit"
+                            },
+                            {
+                                "kind": "OMA",
+                                "applicant": {
+                                    "kind": "OMS",
+                                    "uri": "http://mathhub.info/MitM/core/geometry?Geometry/Common?metric"
+                                },
+                                "arguments": [
+                                    {
+                                        "kind": "OMS",
+                                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"
+                                    },
+                                    {
+                                        "kind": "OMS",
+                                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem?A"
+                                    }
+                                ]
+                            },
+                            {
+                                "kind": "OMA",
+                                "applicant": {
+                                    "kind": "OMS",
+                                    "uri": "http://mathhub.info/MitM/core/arithmetics?RealArithmetics?multiplication"
+                                },
+                                "arguments": [
+                                    {
+                                        "kind": "OMA",
+                                        "applicant": {
+                                            "kind": "OMS",
+                                            "uri": "http://mathhub.info/MitM/Foundation?Trigonometry?tan"
+                                        },
+                                        "arguments": [
+                                            {
+                                                "kind": "OMA",
+                                                "applicant": {
+                                                    "kind": "OMS",
+                                                    "uri": "http://gl.mathhub.info/MMT/LFX/Sigma?Symbols?Projl"
+                                                },
+                                                "arguments": [
+                                                    {
+                                                        "kind": "OMS",
+                                                        "uri": "http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB"
+                                                    }
+                                                ]
+                                            }
+                                        ]
+                                    },
+                                    {
+                                        "kind": "OMA",
+                                        "applicant": {
+                                            "kind": "OMS",
+                                            "uri": "http://gl.mathhub.info/MMT/LFX/Sigma?Symbols?Projl"
+                                        },
+                                        "arguments": [
+                                            {
+                                                "kind": "OMS",
+                                                "uri": "http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC"
+                                            }
+                                        ]
+                                    }
+                                ]
+                            }
+                        ]
+                    },
+                    {
+                        "kind": "OMLIT<String>",
+                        "type": "http://cds.omdoc.org/urtheories?Strings?string",
+                        "value": "OppositeLen Scroll"
+                    }
+                ]
+            },
+            "ref": {
+                "kind": "OMS",
+                "uri": "http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA"
+            },
+            "kind": "veq",
+            "label": "CA"
+        }
+    ],
+    "name": "http://mathhub.info/FrameIT/frameworld?OppositeLen",
+    "path": null
+}
\ No newline at end of file
diff --git a/Assets/StreamingAssets/ScrollView_Server/tmp.json.meta b/Assets/StreamingAssets/ScrollView_Server/tmp.json.meta
new file mode 100644
index 0000000000000000000000000000000000000000..93010ca3a5854f494fdd6d6bc5a1944f35a8f3ad
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/tmp.json.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: debaf813a3dc2474fbafab35f70f7ba4
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/StreamingAssets/ScrollView_Server/tsconfig.json b/Assets/StreamingAssets/ScrollView_Server/tsconfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..453bc1e4df8fde75e44e9864e74dfefa75678f97
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/tsconfig.json
@@ -0,0 +1,112 @@
+{
+  "compilerOptions": {
+    /* Visit https://aka.ms/tsconfig to read more about this file */
+
+    /* Projects */
+    // "incremental": true,                              /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
+    // "composite": true,                                /* Enable constraints that allow a TypeScript project to be used with project references. */
+    // "tsBuildInfoFile": "./.tsbuildinfo",              /* Specify the path to .tsbuildinfo incremental compilation file. */
+    // "disableSourceOfProjectReferenceRedirect": true,  /* Disable preferring source files instead of declaration files when referencing composite projects. */
+    // "disableSolutionSearching": true,                 /* Opt a project out of multi-project reference checking when editing. */
+    // "disableReferencedProjectLoad": true,             /* Reduce the number of projects loaded automatically by TypeScript. */
+
+    /* Language and Environment */
+    "target": "es2016",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
+    // "lib": [],                                        /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+    // "jsx": "preserve",                                /* Specify what JSX code is generated. */
+    // "experimentalDecorators": true,                   /* Enable experimental support for legacy experimental decorators. */
+    // "emitDecoratorMetadata": true,                    /* Emit design-type metadata for decorated declarations in source files. */
+    // "jsxFactory": "",                                 /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
+    // "jsxFragmentFactory": "",                         /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
+    // "jsxImportSource": "",                            /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
+    // "reactNamespace": "",                             /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
+    // "noLib": true,                                    /* Disable including any library files, including the default lib.d.ts. */
+    // "useDefineForClassFields": true,                  /* Emit ECMAScript-standard-compliant class fields. */
+    // "moduleDetection": "auto",                        /* Control what method is used to detect module-format JS files. */
+
+    /* Modules */
+    "module": "commonjs",                                /* Specify what module code is generated. */
+    // "rootDir": "./",                                  /* Specify the root folder within your source files. */
+    // "moduleResolution": "node10",                     /* Specify how TypeScript looks up a file from a given module specifier. */
+    // "baseUrl": "./",                                  /* Specify the base directory to resolve non-relative module names. */
+    // "paths": {},                                      /* Specify a set of entries that re-map imports to additional lookup locations. */
+    // "rootDirs": [],                                   /* Allow multiple folders to be treated as one when resolving modules. */
+    // "typeRoots": [],                                  /* Specify multiple folders that act like './node_modules/@types'. */
+    // "types": [],                                      /* Specify type package names to be included without being referenced in a source file. */
+    // "allowUmdGlobalAccess": true,                     /* Allow accessing UMD globals from modules. */
+    // "moduleSuffixes": [],                             /* List of file name suffixes to search when resolving a module. */
+    // "allowImportingTsExtensions": true,               /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
+    // "rewriteRelativeImportExtensions": true,          /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */
+    // "resolvePackageJsonExports": true,                /* Use the package.json 'exports' field when resolving package imports. */
+    // "resolvePackageJsonImports": true,                /* Use the package.json 'imports' field when resolving imports. */
+    // "customConditions": [],                           /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
+    // "noUncheckedSideEffectImports": true,             /* Check side effect imports. */
+    // "resolveJsonModule": true,                        /* Enable importing .json files. */
+    // "allowArbitraryExtensions": true,                 /* Enable importing files with any extension, provided a declaration file is present. */
+    // "noResolve": true,                                /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
+
+    /* JavaScript Support */
+    "allowJs": true,                                  /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
+    // "checkJs": true,                                  /* Enable error reporting in type-checked JavaScript files. */
+    // "maxNodeModuleJsDepth": 1,                        /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
+
+    /* Emit */
+    // "declaration": true,                              /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
+    // "declarationMap": true,                           /* Create sourcemaps for d.ts files. */
+    // "emitDeclarationOnly": true,                      /* Only output d.ts files and not JavaScript files. */
+    // "sourceMap": true,                                /* Create source map files for emitted JavaScript files. */
+    // "inlineSourceMap": true,                          /* Include sourcemap files inside the emitted JavaScript. */
+    // "noEmit": true,                                   /* Disable emitting files from a compilation. */
+    // "outFile": "./",                                  /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
+    "outDir": "./build",                                   /* Specify an output folder for all emitted files. */
+    // "removeComments": true,                           /* Disable emitting comments. */
+    // "importHelpers": true,                            /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
+    // "downlevelIteration": true,                       /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
+    // "sourceRoot": "",                                 /* Specify the root path for debuggers to find the reference source code. */
+    // "mapRoot": "",                                    /* Specify the location where debugger should locate map files instead of generated locations. */
+    // "inlineSources": true,                            /* Include source code in the sourcemaps inside the emitted JavaScript. */
+    // "emitBOM": true,                                  /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
+    // "newLine": "crlf",                                /* Set the newline character for emitting files. */
+    // "stripInternal": true,                            /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
+    // "noEmitHelpers": true,                            /* Disable generating custom helper functions like '__extends' in compiled output. */
+    // "noEmitOnError": true,                            /* Disable emitting files if any type checking errors are reported. */
+    // "preserveConstEnums": true,                       /* Disable erasing 'const enum' declarations in generated code. */
+    // "declarationDir": "./",                           /* Specify the output directory for generated declaration files. */
+
+    /* Interop Constraints */
+    // "isolatedModules": true,                          /* Ensure that each file can be safely transpiled without relying on other imports. */
+    // "verbatimModuleSyntax": true,                     /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
+    // "isolatedDeclarations": true,                     /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
+    // "allowSyntheticDefaultImports": true,             /* Allow 'import x from y' when a module doesn't have a default export. */
+    "esModuleInterop": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
+    // "preserveSymlinks": true,                         /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
+    "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */
+
+    /* Type Checking */
+    "strict": true,                                      /* Enable all strict type-checking options. */
+    // "noImplicitAny": true,                            /* Enable error reporting for expressions and declarations with an implied 'any' type. */
+    // "strictNullChecks": true,                         /* When type checking, take into account 'null' and 'undefined'. */
+    // "strictFunctionTypes": true,                      /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
+    // "strictBindCallApply": true,                      /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
+    // "strictPropertyInitialization": true,             /* Check for class properties that are declared but not set in the constructor. */
+    // "strictBuiltinIteratorReturn": true,              /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
+    // "noImplicitThis": true,                           /* Enable error reporting when 'this' is given the type 'any'. */
+    // "useUnknownInCatchVariables": true,               /* Default catch clause variables as 'unknown' instead of 'any'. */
+    // "alwaysStrict": true,                             /* Ensure 'use strict' is always emitted. */
+    // "noUnusedLocals": true,                           /* Enable error reporting when local variables aren't read. */
+    // "noUnusedParameters": true,                       /* Raise an error when a function parameter isn't read. */
+    // "exactOptionalPropertyTypes": true,               /* Interpret optional property types as written, rather than adding 'undefined'. */
+    // "noImplicitReturns": true,                        /* Enable error reporting for codepaths that do not explicitly return in a function. */
+    // "noFallthroughCasesInSwitch": true,               /* Enable error reporting for fallthrough cases in switch statements. */
+    // "noUncheckedIndexedAccess": true,                 /* Add 'undefined' to a type when accessed using an index. */
+    // "noImplicitOverride": true,                       /* Ensure overriding members in derived classes are marked with an override modifier. */
+    // "noPropertyAccessFromIndexSignature": true,       /* Enforces using indexed accessors for keys declared using an indexed type. */
+    // "allowUnusedLabels": true,                        /* Disable error reporting for unused labels. */
+    // "allowUnreachableCode": true,                     /* Disable error reporting for unreachable code. */
+
+    /* Completeness */
+    // "skipDefaultLibCheck": true,                      /* Skip type checking .d.ts files that are included with TypeScript. */
+    "skipLibCheck": true                                 /* Skip type checking all .d.ts files. */
+  },
+  "include": ["src/**/*"]
+}
diff --git a/Assets/StreamingAssets/ScrollView_Server/tsconfig.json.meta b/Assets/StreamingAssets/ScrollView_Server/tsconfig.json.meta
new file mode 100644
index 0000000000000000000000000000000000000000..7543b3d623764d396d572da9abf671ed461f8384
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/tsconfig.json.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 26636fc66f0fe77478518ef61066b3c0
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: