From f5a04026fc8591c53cf9c5357bef5512c6f47b51 Mon Sep 17 00:00:00 2001
From: Dale Glass <dale@daleglass.net>
Date: Sun, 13 Feb 2022 23:27:08 +0100
Subject: [PATCH] More files

---
 hifi-content/hifi-worklist-logo.jpg           |   3 +
 hifi-content/high-fidelity-og.jpg             |   3 +
 hifi-content/high-fidelity-og_load-test.jpg   |   3 +
 .../zaru-content-custom-scripts.zip           |   1 +
 .../resources/avatar/animations/idle.fbx      |   1 +
 .../resources/avatar/animations/walk_fwd.fbx  |   3 +
 .../meshes/being_of_light/being_of_light.fbx  |   1 +
 .../BaseMesh_BeingofLight_DiffuseMap.png      |   1 +
 .../BaseMesh_BeingofLight_EmissiveMap.png     |   1 +
 .../BaseMesh_BeingofLight_NormalMap.png       |   1 +
 .../resources/meshes/defaultAvatar_full.fst   |   1 +
 hifi-content/howard/scripts/dev-welcome.js    |  64 ++++
 .../scripts/tests/performance/crowd-agent.js  | 166 +++++++++
 .../scripts/tests/performance/domain-check.js | 345 ++++++++++++++++++
 .../tests/performance/screamingAvatarAC.js    |  39 ++
 .../scripts/tests/performance/summon.js       | 157 ++++++++
 hifi-content/howard/sounds/hello.wav          |   3 +
 hifi-content/howard/sounds/piano1.wav         |   3 +
 .../howard/zaru-content-custom-scripts.zip    |   3 +
 .../howard/zaru-content-default-scripts.zip   |   3 +
 .../Cartoony_Computer/CCTV_image-redigert.jpg |   3 +
 .../Cartoony_Computer/Cartoony_Computer.FBX   |   3 +
 .../Cartoony_Computer/Cartoony_Computer.max   |   3 +
 .../Cartoony_Computer/Cartoony_Computer.mtl   |  84 +++++
 .../Cartoony_Computer/Cartoony_Computer.obj   |   3 +
 .../Cartoony_Computer[max2010].max            |   3 +
 hifi-content/howell/Prototypes/GOT/GOT.png    |   3 +
 .../GOT/drogon finished with base2.obj        |   3 +
 .../howell/Prototypes/GOT/drogon-statue.fbx   |   3 +
 .../Prototypes/Idle_app/Hanging Idle.fbx      |   3 +
 .../howell/Prototypes/Idle_app/Happy.fbx      |   3 +
 .../Prototypes/Idle_app/Male Laying Pose.fbx  |   3 +
 .../howell/Prototypes/Idle_app/Ninja Idle.fbx |   3 +
 .../howell/Prototypes/Idle_app/Push Up.fbx    |   3 +
 .../howell/Prototypes/Idle_app/mat_laying.fbx |   3 +
 .../howell/Prototypes/JAT_test/JATScritp.js   | 344 +++++++++++++++++
 .../howell/Prototypes/JAT_test/config.json    |  27 ++
 .../howell/Prototypes/andy_bot_bingos.js      | 125 +++++++
 hifi-content/howell/Prototypes/andy_bots.js   | 125 +++++++
 .../Prototypes/andy_bots_futvrelands.js       | 203 +++++++++++
 hifi-content/howell/Prototypes/best_game.jpg  |   3 +
 .../assignmentClientManager_andy_test.js      | 247 +++++++++++++
 hifi-content/howell/Prototypes/bouncer.js     | 270 ++++++++++++++
 hifi-content/howell/Prototypes/crabble.png    |   3 +
 .../howell/Prototypes/dog_skull/dogskull.mtl  |  14 +
 .../howell/Prototypes/dog_skull/dogskull.obj  |   3 +
 .../Prototypes/dog_skull/dogskull_u1_v1.jpg   |   3 +
 hifi-content/howell/Prototypes/glasses.jpg    |   3 +
 .../howell/Prototypes/jat_test2/JATScritp.js  |   1 +
 .../howell/Prototypes/jat_test2/config.json   |   1 +
 .../howell/Prototypes/jat_test3/JATScritp.js  |   1 +
 .../howell/Prototypes/jat_test3/config.json   |  27 ++
 .../howell/Prototypes/neon_snowflake.jpg      |   3 +
 hifi-content/howell/Prototypes/neonturkey.jpg |   3 +
 hifi-content/howell/Prototypes/pants.JPG      |   3 +
 hifi-content/howell/Prototypes/pumpkins.jpg   |   3 +
 hifi-content/howell/Prototypes/satdium.fbx    |   3 +
 hifi-content/howell/Prototypes/shirt.jpg      |   3 +
 hifi-content/howell/Prototypes/snowflake.PNG  |   3 +
 hifi-content/howell/Prototypes/space.jpg      |   3 +
 hifi-content/howell/Prototypes/space2.jpg     |   3 +
 .../howell/Prototypes/team_directory.PNG      |   3 +
 hifi-content/howell/Prototypes/turkeybleh.png |   3 +
 .../howell/Prototypes/ugly_sweater.jpg        |   3 +
 .../Prototypes/wheel_of_current_events.png    |   3 +
 hifi-content/howell/bots/AVATAR_TEST1.hfr     |   3 +
 hifi-content/howell/bots/AVATAR_TEST10.hfr    |   3 +
 hifi-content/howell/bots/AVATAR_TEST11.hfr    |   3 +
 hifi-content/howell/bots/AVATAR_TEST12.hfr    |   3 +
 hifi-content/howell/bots/AVATAR_TEST13.hfr    |   3 +
 hifi-content/howell/bots/AVATAR_TEST14.hfr    |   3 +
 hifi-content/howell/bots/AVATAR_TEST15.hfr    |   3 +
 hifi-content/howell/bots/AVATAR_TEST16.hfr    |   3 +
 hifi-content/howell/bots/AVATAR_TEST17.hfr    |   3 +
 hifi-content/howell/bots/AVATAR_TEST18.hfr    |   3 +
 hifi-content/howell/bots/AVATAR_TEST19.hfr    |   3 +
 hifi-content/howell/bots/AVATAR_TEST2.hfr     |   3 +
 hifi-content/howell/bots/AVATAR_TEST20.hfr    |   3 +
 hifi-content/howell/bots/AVATAR_TEST3.hfr     |   3 +
 hifi-content/howell/bots/AVATAR_TEST4.hfr     |   3 +
 hifi-content/howell/bots/AVATAR_TEST5.hfr     |   3 +
 hifi-content/howell/bots/AVATAR_TEST6.hfr     |   3 +
 hifi-content/howell/bots/AVATAR_TEST7.hfr     |   3 +
 hifi-content/howell/bots/AVATAR_TEST8.hfr     |   3 +
 hifi-content/howell/bots/AVATAR_TEST9.hfr     |   3 +
 hifi-content/howell/bots/_AVATAR_TEST5.hfr    |   1 +
 hifi-content/howell/bots_new/AVATAR_TEST1.hfr |   3 +
 .../howell/usertesting/can_you_see_me.txt     |   1 +
 .../huffman/avatars/tubeboy/tubeboy.fst       | 131 +++++++
 .../avatars/tubeboy/tubeboy/tubeboy.fbx       |   3 +
 .../huffman/ctf/Portal-Red-Blue.svo.json      | 175 +++++++++
 hifi-content/huffman/ctf/README.md            |  24 ++
 hifi-content/huffman/ctf/ballClientEntity.js  |  67 ++++
 hifi-content/huffman/ctf/firework.js          | 147 ++++++++
 hifi-content/huffman/ctf/goalClientEntity.js  |  50 +++
 .../huffman/ctf/gunSpawnerClientEntity.js     | 124 +++++++
 hifi-content/huffman/ctf/models/portalgun.fbx |   1 +
 .../huffman/ctf/models/portalgun_blue.fbx     |   1 +
 .../huffman/ctf/models/portalgun_collider.obj |   1 +
 .../huffman/ctf/models/portalgun_red.fbx      |   1 +
 .../huffman/ctf/origina_portal_gun.js         | 210 +++++++++++
 .../huffman/ctf/portalBulletClientEntity.js   |  47 +++
 .../huffman/ctf/portalGunClientEntity.js      | 222 +++++++++++
 hifi-content/huffman/ctf/portalgun.json       |  81 ++++
 hifi-content/huffman/ctf/sounds/gunFire.wav   |   3 +
 .../huffman/ctf/sounds/pong_sound.wav         |   3 +
 hifi-content/huffman/ctf/sounds/teleport.raw  | Bin 0 -> 106592 bytes
 hifi-content/huffman/ctf/spawnPortalGun.js    |  99 +++++
 hifi-content/huffman/ctf/utils.js             |  93 +++++
 hifi-content/huffman/essTest.js               |   9 +
 110 files changed, 3924 insertions(+)
 create mode 100644 hifi-content/hifi-worklist-logo.jpg
 create mode 100644 hifi-content/high-fidelity-og.jpg
 create mode 100644 hifi-content/high-fidelity-og_load-test.jpg
 create mode 120000 hifi-content/howard/production/zaru-content-custom-scripts.zip
 create mode 120000 hifi-content/howard/resources/avatar/animations/idle.fbx
 create mode 100644 hifi-content/howard/resources/avatar/animations/walk_fwd.fbx
 create mode 120000 hifi-content/howard/resources/meshes/being_of_light/being_of_light.fbx
 create mode 120000 hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_DiffuseMap.png
 create mode 120000 hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_EmissiveMap.png
 create mode 120000 hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_NormalMap.png
 create mode 120000 hifi-content/howard/resources/meshes/defaultAvatar_full.fst
 create mode 100644 hifi-content/howard/scripts/dev-welcome.js
 create mode 100644 hifi-content/howard/scripts/tests/performance/crowd-agent.js
 create mode 100644 hifi-content/howard/scripts/tests/performance/domain-check.js
 create mode 100644 hifi-content/howard/scripts/tests/performance/screamingAvatarAC.js
 create mode 100644 hifi-content/howard/scripts/tests/performance/summon.js
 create mode 100644 hifi-content/howard/sounds/hello.wav
 create mode 100644 hifi-content/howard/sounds/piano1.wav
 create mode 100644 hifi-content/howard/zaru-content-custom-scripts.zip
 create mode 100644 hifi-content/howard/zaru-content-default-scripts.zip
 create mode 100644 hifi-content/howell/Prototypes/Cartoony_Computer/CCTV_image-redigert.jpg
 create mode 100644 hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.FBX
 create mode 100644 hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.max
 create mode 100644 hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.mtl
 create mode 100644 hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.obj
 create mode 100644 hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer[max2010].max
 create mode 100644 hifi-content/howell/Prototypes/GOT/GOT.png
 create mode 100644 hifi-content/howell/Prototypes/GOT/drogon finished with base2.obj
 create mode 100644 hifi-content/howell/Prototypes/GOT/drogon-statue.fbx
 create mode 100644 hifi-content/howell/Prototypes/Idle_app/Hanging Idle.fbx
 create mode 100644 hifi-content/howell/Prototypes/Idle_app/Happy.fbx
 create mode 100644 hifi-content/howell/Prototypes/Idle_app/Male Laying Pose.fbx
 create mode 100644 hifi-content/howell/Prototypes/Idle_app/Ninja Idle.fbx
 create mode 100644 hifi-content/howell/Prototypes/Idle_app/Push Up.fbx
 create mode 100644 hifi-content/howell/Prototypes/Idle_app/mat_laying.fbx
 create mode 100644 hifi-content/howell/Prototypes/JAT_test/JATScritp.js
 create mode 100644 hifi-content/howell/Prototypes/JAT_test/config.json
 create mode 100644 hifi-content/howell/Prototypes/andy_bot_bingos.js
 create mode 100644 hifi-content/howell/Prototypes/andy_bots.js
 create mode 100644 hifi-content/howell/Prototypes/andy_bots_futvrelands.js
 create mode 100644 hifi-content/howell/Prototypes/best_game.jpg
 create mode 100644 hifi-content/howell/Prototypes/bot_player_content_v4/assignmentClientManager_andy_test.js
 create mode 100644 hifi-content/howell/Prototypes/bouncer.js
 create mode 100644 hifi-content/howell/Prototypes/crabble.png
 create mode 100644 hifi-content/howell/Prototypes/dog_skull/dogskull.mtl
 create mode 100644 hifi-content/howell/Prototypes/dog_skull/dogskull.obj
 create mode 100644 hifi-content/howell/Prototypes/dog_skull/dogskull_u1_v1.jpg
 create mode 100644 hifi-content/howell/Prototypes/glasses.jpg
 create mode 120000 hifi-content/howell/Prototypes/jat_test2/JATScritp.js
 create mode 120000 hifi-content/howell/Prototypes/jat_test2/config.json
 create mode 120000 hifi-content/howell/Prototypes/jat_test3/JATScritp.js
 create mode 100644 hifi-content/howell/Prototypes/jat_test3/config.json
 create mode 100644 hifi-content/howell/Prototypes/neon_snowflake.jpg
 create mode 100644 hifi-content/howell/Prototypes/neonturkey.jpg
 create mode 100644 hifi-content/howell/Prototypes/pants.JPG
 create mode 100644 hifi-content/howell/Prototypes/pumpkins.jpg
 create mode 100644 hifi-content/howell/Prototypes/satdium.fbx
 create mode 100644 hifi-content/howell/Prototypes/shirt.jpg
 create mode 100644 hifi-content/howell/Prototypes/snowflake.PNG
 create mode 100644 hifi-content/howell/Prototypes/space.jpg
 create mode 100644 hifi-content/howell/Prototypes/space2.jpg
 create mode 100644 hifi-content/howell/Prototypes/team_directory.PNG
 create mode 100644 hifi-content/howell/Prototypes/turkeybleh.png
 create mode 100644 hifi-content/howell/Prototypes/ugly_sweater.jpg
 create mode 100644 hifi-content/howell/Prototypes/wheel_of_current_events.png
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST1.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST10.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST11.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST12.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST13.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST14.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST15.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST16.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST17.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST18.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST19.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST2.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST20.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST3.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST4.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST5.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST6.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST7.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST8.hfr
 create mode 100644 hifi-content/howell/bots/AVATAR_TEST9.hfr
 create mode 120000 hifi-content/howell/bots/_AVATAR_TEST5.hfr
 create mode 100644 hifi-content/howell/bots_new/AVATAR_TEST1.hfr
 create mode 100644 hifi-content/howell/usertesting/can_you_see_me.txt
 create mode 100644 hifi-content/huffman/avatars/tubeboy/tubeboy.fst
 create mode 100644 hifi-content/huffman/avatars/tubeboy/tubeboy/tubeboy.fbx
 create mode 100644 hifi-content/huffman/ctf/Portal-Red-Blue.svo.json
 create mode 100644 hifi-content/huffman/ctf/README.md
 create mode 100644 hifi-content/huffman/ctf/ballClientEntity.js
 create mode 100644 hifi-content/huffman/ctf/firework.js
 create mode 100644 hifi-content/huffman/ctf/goalClientEntity.js
 create mode 100644 hifi-content/huffman/ctf/gunSpawnerClientEntity.js
 create mode 120000 hifi-content/huffman/ctf/models/portalgun.fbx
 create mode 120000 hifi-content/huffman/ctf/models/portalgun_blue.fbx
 create mode 120000 hifi-content/huffman/ctf/models/portalgun_collider.obj
 create mode 120000 hifi-content/huffman/ctf/models/portalgun_red.fbx
 create mode 100644 hifi-content/huffman/ctf/origina_portal_gun.js
 create mode 100644 hifi-content/huffman/ctf/portalBulletClientEntity.js
 create mode 100644 hifi-content/huffman/ctf/portalGunClientEntity.js
 create mode 100644 hifi-content/huffman/ctf/portalgun.json
 create mode 100644 hifi-content/huffman/ctf/sounds/gunFire.wav
 create mode 100644 hifi-content/huffman/ctf/sounds/pong_sound.wav
 create mode 100644 hifi-content/huffman/ctf/sounds/teleport.raw
 create mode 100644 hifi-content/huffman/ctf/spawnPortalGun.js
 create mode 100644 hifi-content/huffman/ctf/utils.js
 create mode 100644 hifi-content/huffman/essTest.js

diff --git a/hifi-content/hifi-worklist-logo.jpg b/hifi-content/hifi-worklist-logo.jpg
new file mode 100644
index 000000000..aea9a6f10
--- /dev/null
+++ b/hifi-content/hifi-worklist-logo.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:55e0762d0f18abcc9774c54991707b651ddde44aecb3f659bdf74ffb6b902e4e
+size 57744
diff --git a/hifi-content/high-fidelity-og.jpg b/hifi-content/high-fidelity-og.jpg
new file mode 100644
index 000000000..51847777a
--- /dev/null
+++ b/hifi-content/high-fidelity-og.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:11dea34a973c9a92a8763d60e0fa83d008c256f67666be8fabf0ff877314808f
+size 249288
diff --git a/hifi-content/high-fidelity-og_load-test.jpg b/hifi-content/high-fidelity-og_load-test.jpg
new file mode 100644
index 000000000..8057cf6a5
--- /dev/null
+++ b/hifi-content/high-fidelity-og_load-test.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:723ed0248227f0b23c10c8f588fc52e4b99c152a11ab86da5d6e0da9fb552b65
+size 191882
diff --git a/hifi-content/howard/production/zaru-content-custom-scripts.zip b/hifi-content/howard/production/zaru-content-custom-scripts.zip
new file mode 120000
index 000000000..7804ca9ad
--- /dev/null
+++ b/hifi-content/howard/production/zaru-content-custom-scripts.zip
@@ -0,0 +1 @@
+../zaru-content-custom-scripts.zip
\ No newline at end of file
diff --git a/hifi-content/howard/resources/avatar/animations/idle.fbx b/hifi-content/howard/resources/avatar/animations/idle.fbx
new file mode 120000
index 000000000..28932e2a2
--- /dev/null
+++ b/hifi-content/howard/resources/avatar/animations/idle.fbx
@@ -0,0 +1 @@
+../../../../DomainContent/AvatarStore-Backup/BodyMart/idle.fbx
\ No newline at end of file
diff --git a/hifi-content/howard/resources/avatar/animations/walk_fwd.fbx b/hifi-content/howard/resources/avatar/animations/walk_fwd.fbx
new file mode 100644
index 000000000..c46983c2d
--- /dev/null
+++ b/hifi-content/howard/resources/avatar/animations/walk_fwd.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:41e68ef30fcab9aca97307fa815f401477aa7550668beb2af8b35c7a1bd112e5
+size 309024
diff --git a/hifi-content/howard/resources/meshes/being_of_light/being_of_light.fbx b/hifi-content/howard/resources/meshes/being_of_light/being_of_light.fbx
new file mode 120000
index 000000000..adc65df8f
--- /dev/null
+++ b/hifi-content/howard/resources/meshes/being_of_light/being_of_light.fbx
@@ -0,0 +1 @@
+../../../../lincoln/avatars/being_of_light.fbx
\ No newline at end of file
diff --git a/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_DiffuseMap.png b/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_DiffuseMap.png
new file mode 120000
index 000000000..8f6222018
--- /dev/null
+++ b/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_DiffuseMap.png
@@ -0,0 +1 @@
+../../../../../Avatars/production/being_of_light/textures/BaseMesh_BeingofLight_DiffuseMap.png
\ No newline at end of file
diff --git a/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_EmissiveMap.png b/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_EmissiveMap.png
new file mode 120000
index 000000000..55f17c005
--- /dev/null
+++ b/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_EmissiveMap.png
@@ -0,0 +1 @@
+../../../../../Avatars/production/being_of_light/textures/BaseMesh_BeingofLight_EmissiveMap.png
\ No newline at end of file
diff --git a/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_NormalMap.png b/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_NormalMap.png
new file mode 120000
index 000000000..fedb67990
--- /dev/null
+++ b/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_NormalMap.png
@@ -0,0 +1 @@
+../../../../../Avatars/production/being_of_light/textures/BaseMesh_BeingofLight_NormalMap.png
\ No newline at end of file
diff --git a/hifi-content/howard/resources/meshes/defaultAvatar_full.fst b/hifi-content/howard/resources/meshes/defaultAvatar_full.fst
new file mode 120000
index 000000000..22ea22bcf
--- /dev/null
+++ b/hifi-content/howard/resources/meshes/defaultAvatar_full.fst
@@ -0,0 +1 @@
+../../../lincoln/avatars/being_of_light.fst
\ No newline at end of file
diff --git a/hifi-content/howard/scripts/dev-welcome.js b/hifi-content/howard/scripts/dev-welcome.js
new file mode 100644
index 000000000..4dbcf12ad
--- /dev/null
+++ b/hifi-content/howard/scripts/dev-welcome.js
@@ -0,0 +1,64 @@
+var typeBlacklist = ["Zone"];    /* for now, disallow all zone entities */
+var center = {x: 0, y: 0, z: 0}; /* also nothing can move within 5 meters of 0,0,0 */
+var radius = 5;
+var epsilon = 0.01;
+var aBitMore = 5 * (1 + epsilon);
+var staticBounceSpeed = 0.5;     /* If edit within radius that has no velocity. */
+var Vec3 = {
+    distance: function distance(a, b) {
+        var x = a.x - b.x,
+            y = a.y - b.y,
+            z = a.z - b.z;
+        return Math.sqrt((x * x) + (y * y) + (z * z));
+    },
+    ZERO: {x: 0, y: 0, z: 0},
+    length: function length(v) {
+        return Vec3.distance(Vec3.ZERO, v);
+    },
+    multiply: function multiply(s, v) {
+        return {x: s * v.x, y: s * v.y, z: s * v.z};
+    },
+    normalize: function normalize(v) {
+        var length = Vec3.length(v);
+        return Vec3.multiply(1/length, v);
+    }
+};
+
+function filter(p, filterType) {
+    if (p.type && (typeBlacklist.indexOf(p.type) != -1)) {
+        print("filtering out " + p.type + " entity!");
+        return false
+    }
+    if (p.position) {
+        var distance = Vec3.distance(center, p.position);
+        var reject = distance <= radius;
+        var normal;
+        if (reject) {
+            print('rejecting type', filterType, 'packet near origin');
+            if (filterType === Entities.ADD_FILTER_TYPE) {
+                return false;
+            } else { /* Others are Entities.EDIT_FILTER_TYPE and Entities.PHYSICS_FILTER_TYPE. */
+                normal = Vec3.normalize(p.position);
+                p.position = Vec3.multiply(aBitMore, normal);
+                p.velocity = (p.velocity && Vec3.length(p.velocity) > epsilon) ?
+                    Vec3.multiply(-1, p.velocity) : Vec3.multiply(staticBounceSpeed, normal);
+                p.acceleration = Vec3.ZERO;
+            }
+        }
+    }
+    if (p.dimensions && (filterType !== Entities.ADD_FILTER_TYPE)) {
+        if (p.dimensions.x > 11) {
+            p.dimensions.x = 11;
+            print('capping x dimension');
+        }
+        if (p.dimensions.y > 11) {
+            p.dimensions.y = 11;
+            print('capping y dimension');
+        }
+        if (p.dimensions.z > 11) {
+            p.dimensions.z = 11;
+            print('capping z dimension');
+        }
+    }
+    return p;
+}
diff --git a/hifi-content/howard/scripts/tests/performance/crowd-agent.js b/hifi-content/howard/scripts/tests/performance/crowd-agent.js
new file mode 100644
index 000000000..708856a82
--- /dev/null
+++ b/hifi-content/howard/scripts/tests/performance/crowd-agent.js
@@ -0,0 +1,166 @@
+"use strict";
+/*jslint vars: true, plusplus: true*/
+/*global Agent, Avatar, Script, Entities, Vec3, Quat, print*/
+//
+//  crowd-agent.js
+//  scripts/developer/tests/performance/
+//
+//  Created by Howard Stearns on 9/29/16.
+//  Copyright 2016 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+//  Add this to domain-settings scripts url with n instances. It will lie dormant until
+//  a script like summon.js calls up to n avatars to be around you.
+
+var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd";
+
+print('crowd-agent version 5');
+
+/* Observations:
+- File urls for AC scripts silently fail. Use a local server (e.g., python SimpleHTTPServer) for development.
+- URLs are cached regardless of server headers. Must use cache-defeating query parameters.
+- JSON.stringify(Avatar) silently fails (even when Agent.isAvatar)
+- If you run from a dev build directory, you must link assignment-client/<target>/resources to ../../interface/<target>/resources
+*/
+
+function messageSend(message) {
+    Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message));
+}
+
+function getSound(data, callback) { // callback(sound) when downloaded (which may be immediate).
+    var sound = SoundCache.getSound(data.url);
+    if (sound.downloaded) {
+        return callback(sound);
+    }
+    function onDownloaded() {
+        sound.ready.disconnect(onDownloaded);
+        callback(sound);
+    }
+    sound.ready.connect(onDownloaded);
+}
+function onFinishedPlaying() {
+    messageSend({key: 'finishedSound'});
+}
+
+var attachment;
+var stopper;
+function clearStopper() {
+    if (!stopper) {
+        return;
+    }
+    Script.clearTimeout(stopper);
+    stopper = null;
+}
+function stopAgent(parameters) {
+    function stop() {
+        clearStopper();
+        if (attachment) {
+            Avatar.detachOne(attachment.modelURL, attachment.jointName);
+            attachment = undefined;
+        }
+        Agent.isListeningToAudioStream = false;
+        Agent.isAvatar = false;
+        print('crowd-agent stopped', JSON.stringify(parameters), JSON.stringify(Agent));
+    }
+    // Shutting down lots of agents at once can be hard on other parts of the system. (See fogbugz 2095.)
+    // For now, accept a parameter to delay for the given number of milliseconds before stopping.
+    // (We cannot count on summoning scripts to spread out the STOP messages, because they might be doing so
+    // on scriptEnding, in which case they are not allowed to create new delays.)
+    if (parameters.delay) {
+        if (!stopper) { // Let the first stopper do the deed.
+            stopper = Script.setTimeout(stop, parameters.delay);
+        }
+    } else {
+        stop();
+    }
+}
+
+
+var MILLISECONDS_IN_SECOND = 1000;
+function startAgent(parameters) { // Can also be used to update.
+    print('crowd-agent starting params', JSON.stringify(parameters), JSON.stringify(Agent));
+    clearStopper();
+    var wasOff = !Agent.isAvatar;
+    Agent.isAvatar = true;
+    if (parameters.displayName !== undefined) {
+        Avatar.displayName = parameters.displayName;
+    }
+    if (parameters.position) {
+        Avatar.position = parameters.position;
+    }
+    if (parameters.orientation) {
+        Avatar.orientation = parameters.orientation;
+    }
+    if (parameters.skeletonModelURL) {
+        Avatar.skeletonModelURL = parameters.skeletonModelURL;
+    }
+    if (parameters.listen != undefined) {
+        Agent.isListeningToAudioStream = parameters.listen; // Send silence when not chattering.
+    } else if (wasOff) {
+        Agent.isListeningToAudioStream = true;
+    }
+    if (parameters.soundData) {
+        getSound(parameters.soundData, function (sound) {
+            Script.setTimeout(onFinishedPlaying, sound.duration * MILLISECONDS_IN_SECOND);
+            Agent.playAvatarSound(sound);
+        });
+    }
+    if (parameters.animationData) {
+        var data = parameters.animationData;
+        Avatar.startAnimation(data.url, data.fps || 30, 1.0, (data.loopFlag === undefined) ? true : data.loopFlag, false, data.startFrame || 0, data.endFrame);
+    }
+    if (parameters.attachment) {
+        attachment = parameters.attachment;
+        Avatar.attach(attachment.modelURL, attachment.jointName, attachment.translation, attachment.rotation, attachment.scale, attachment.isSoft);
+    } else {
+        attachment = undefined;
+    }
+    print('crowd-agent avatars started');
+}
+
+function messageHandler(channel, messageString, senderID) {
+    if (channel !== MESSAGE_CHANNEL) {
+        return;
+    }
+    print('crowd-agent message', channel, messageString, senderID);
+    if (Agent.sessionUUID === senderID) { // ignore my own
+        return;
+    }
+    var message = {};
+    try {
+        message = JSON.parse(messageString);
+    } catch (e) {
+        print(e);
+    }
+    switch (message.key) {
+    case "HELO":
+        messageSend({key: 'hello'}); // Allow the coordinator to count responses and make assignments.
+        break;
+    case 'hello': // ignore responses (e.g., from other agents)
+    case 'finishedSound':
+        break;
+    case "SUMMON":
+        if (message.rcpt === Agent.sessionUUID) {
+            startAgent(message);
+        }
+        break;
+    case "STOP":
+        if (message.rcpt === Agent.sessionUUID) {
+            stopAgent(message);
+        }
+        break;
+    default:
+        print("crowd-agent received unrecognized message:", channel, messageString, senderID);
+    }
+}
+Messages.subscribe(MESSAGE_CHANNEL);
+Messages.messageReceived.connect(messageHandler);
+
+Script.scriptEnding.connect(function () {
+    print('crowd-agent shutting down');
+    Messages.messageReceived.disconnect(messageHandler);
+    Messages.unsubscribe(MESSAGE_CHANNEL);
+    print('crowd-agent unsubscribed');
+});
diff --git a/hifi-content/howard/scripts/tests/performance/domain-check.js b/hifi-content/howard/scripts/tests/performance/domain-check.js
new file mode 100644
index 000000000..b4bf4569c
--- /dev/null
+++ b/hifi-content/howard/scripts/tests/performance/domain-check.js
@@ -0,0 +1,345 @@
+"use strict";
+/*jslint vars: true, plusplus: true*/
+/*globals Script, MyAvatar, Quat, Vec3, Render, ScriptDiscoveryService, Window, LODManager, Entities, Messages, AvatarList, Menu, Stats, HMD, location, print*/
+//
+//  loadedMachine.js
+//  scripts/developer/tests/
+//
+//  Created by Howard Stearns on 6/6/16.
+//  Copyright 2016 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+//  Confirms that the specified domain is operating within specified constraints.
+
+var MINIMUM_DESKTOP_FRAMERATE = 57; // frames per second
+var MINIMUM_HMD_FRAMERATE = 86;
+var EXPECTED_DESKTOP_FRAMERATE = 60;
+var EXPECTED_HMD_FRAMERATE = 90;
+var NOMINAL_LOAD_TIME = 30;         // seconds
+var MAXIMUM_LOAD_TIME = NOMINAL_LOAD_TIME * 2;
+var MINIMUM_AVATARS = 25; // changeable by prompt
+
+// If we add or remove things too quickly, we get problems (e.g., audio, fogbugz 2095).
+// For now, spread them out this timing apart.
+var SPREAD_TIME_MS = 500;
+
+var DENSITY = 0.3; // square meters per person. Some say 10 sq ft is arm's length (0.9m^2), 4.5 is crowd (0.4m^2), 2.5 is mosh pit (0.2m^2).
+var SOUND_DATA = {url: "http://hifi-content.s3.amazonaws.com/howard/sounds/piano1.wav"};
+var AVATARS_CHATTERING_AT_ONCE = 4; // How many of the agents should we request to play SOUND at once.
+var NEXT_SOUND_SPREAD = 500; // millisecond range of how long to wait after one sound finishes, before playing the next
+var ANIMATION_DATA = {
+    "url": "http://hifi-content.s3.amazonaws.com/howard/resources/avatar/animations/idle.fbx",
+    // "url": "http://hifi-content.s3.amazonaws.com/howard/resources/avatar/animations/walk_fwd.fbx", // alternative example
+    "startFrame": 0.0,
+    "endFrame": 300.0,
+    "timeScale": 1.0,
+    "loopFlag": true
+};
+
+var version = 4;
+function debug() {
+    print.apply(null, [].concat.apply(['hrs fixme', version], [].map.call(arguments, JSON.stringify)));
+}
+
+function canonicalizePlacename(name) {
+    var prefix = 'dev-';
+    name = name.toLowerCase();
+    if (name.indexOf(prefix) === 0) {
+        name = name.slice(prefix.length);
+    }
+    return name;
+}
+var cachePlaces = ['localhost', 'welcome'].map(canonicalizePlacename); // For now, list the lighter weight one first.
+var defaultPlace = location.hostname;
+var prompt = "domain-check.js version " + version + "\n\nWhat place should we enter?";
+debug(cachePlaces, defaultPlace, prompt);
+var entryPlace = Window.prompt(prompt, defaultPlace);
+var runTribbles = Window.confirm("Run tribbles?\n\n\
+At most, only one participant should say yes.");
+MINIMUM_AVATARS = parseInt(Window.prompt("Total avatars (including yourself and any already present)?", MINIMUM_AVATARS.toString()) || "0", 10);
+AVATARS_CHATTERING_AT_ONCE = MINIMUM_AVATARS ? parseInt(Window.prompt("Number making sound?", Math.min(MINIMUM_AVATARS - 1, AVATARS_CHATTERING_AT_ONCE).toString()) || "0", 10) : 0;
+
+function placesMatch(a, b) { // handling case and 'dev-' variations
+    return canonicalizePlacename(a) === canonicalizePlacename(b);
+}
+function isNowIn(place) { // true if currently in specified place
+    placesMatch(location.hostname, place);
+}
+
+function go(place) { // handle (dev-)welcome in the appropriate version-specific way
+    debug('go', place);
+    if (placesMatch(place, 'welcome')) {
+        location.goToEntry();
+    } else {
+        location.handleLookupString(place);
+    }
+}
+
+var spread = Math.sqrt(MINIMUM_AVATARS * DENSITY); // meters
+var turnSpread = 90; // How many degrees should turn from front range over.
+
+function coord() { return (Math.random() * spread) - (spread / 2); }  // randomly distribute a coordinate zero += spread/2.
+function contains(array, item) { return array.indexOf(item) >= 0; }
+function without(array, itemsToRemove) { return array.filter(function (item) { return !contains(itemsToRemove, item); }); }
+function nextAfter(array, id) { // Wrapping next element in array after id.
+    var index = array.indexOf(id) + 1;
+    return array[(index >= array.length) ? 0 : index];
+}
+
+var summonedAgents = [];
+var chattering = [];
+var accumulatedDelay = 0;
+var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd";
+function messageSend(message) {
+    Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message));
+}
+function messageHandler(channel, messageString, senderID) {
+    if (channel !== MESSAGE_CHANNEL) {
+        return;
+    }
+    debug('message', channel, messageString, senderID);
+    if (MyAvatar.sessionUUID === senderID) { // ignore my own
+        return;
+    }
+    var message = {}, avatarIdentifiers;
+    try {
+        message = JSON.parse(messageString);
+    } catch (e) {
+        print(e);
+    }
+    switch (message.key) {
+    case "hello":
+        Script.setTimeout(function () {
+            // There can be avatars we've summoned that do not yet appear in the AvatarList.
+            avatarIdentifiers = without(AvatarList.getAvatarIdentifiers(), summonedAgents);
+            debug('present', avatarIdentifiers, summonedAgents);
+            if ((summonedAgents.length + avatarIdentifiers.length) < MINIMUM_AVATARS) {
+                var chatter = chattering.length < AVATARS_CHATTERING_AT_ONCE;
+                if (chatter) {
+                    chattering.push(senderID);
+                }
+                summonedAgents.push(senderID);
+                messageSend({
+                    key: 'SUMMON',
+                    rcpt: senderID,
+                    position: Vec3.sum(MyAvatar.position, {x: coord(), y: 0, z: coord()}),
+                    orientation: Quat.fromPitchYawRollDegrees(0, Quat.safeEulerAngles(MyAvatar.orientation).y + (turnSpread * (Math.random() - 0.5)), 0),
+                    soundData: chatter && SOUND_DATA,
+                    listen: true,
+                    skeletonModelURL: "http://hifi-content.s3.amazonaws.com/howard/resources/meshes/defaultAvatar_full.fst",
+                    animationData: ANIMATION_DATA
+                });
+            }
+        }, accumulatedDelay);
+        accumulatedDelay += SPREAD_TIME_MS; // assume we'll get all the hello respsponses more or less together.
+        break;
+    case "finishedSound": // Give someone else a chance.
+        chattering = without(chattering, [senderID]);
+        Script.setTimeout(function () {
+            messageSend({
+                key: 'SUMMON',
+                rcpt: nextAfter(without(summonedAgents, chattering), senderID),
+                soundData: SOUND_DATA
+            });
+        }, Math.random() * NEXT_SOUND_SPREAD);
+        break;
+    case "HELO":
+        Window.alert("Someone else is summoning avatars.");
+        break;
+    default:
+        print("crowd-agent received unrecognized message:", messageString);
+    }
+}
+Messages.subscribe(MESSAGE_CHANNEL);
+Messages.messageReceived.connect(messageHandler);
+Script.scriptEnding.connect(function () {
+    debug('stopping agents', summonedAgents);
+    Messages.messageReceived.disconnect(messageHandler); // don't respond to any messages during shutdown
+    accumulatedDelay = 0;
+    summonedAgents.forEach(function (id) {
+        messageSend({key: 'STOP', rcpt: id, delay: accumulatedDelay});
+        accumulatedDelay += SPREAD_TIME_MS;
+    });
+    debug('agents stopped');
+    Messages.unsubscribe(MESSAGE_CHANNEL);
+    debug('unsubscribed');
+});
+
+var fail = false, results = "";
+function addResult(label, actual, nominal, minimum, maximum) {
+    if ((minimum !== undefined) && (actual < minimum)) {
+        fail = ' FAILED: ' + label + ' below ' + minimum;
+    }
+    if ((maximum !== undefined) && (actual > maximum)) {
+        fail = ' FAILED: ' + label + ' above ' + maximum;
+    }
+    results += "\n" + label + ": " + actual.toFixed(0) + " (" + ((100 * actual) / nominal).toFixed(0) + "%)";
+}
+function giveReport() {
+    Window.alert(entryPlace + (fail || " OK") + "\n" + results + "\nwith " + summonedAgents.length + " avatars added,\nand " + AVATARS_CHATTERING_AT_ONCE + " making noise.");
+}
+
+// Tests are performed domain-wide, at full LOD
+var initialLodIsAutomatic = LODManager.getAutomaticLODAdjust();
+var LOD = 32768 * 400;
+LODManager.setAutomaticLODAdjust(false);
+LODManager.setOctreeSizeScale(LOD);
+Script.scriptEnding.connect(function () { LODManager.setAutomaticLODAdjust(initialLodIsAutomatic); });
+
+function startTwirl(targetRotation, degreesPerUpdate, interval, strafeDistance, optionalCallback) {
+    var initialRotation = Quat.safeEulerAngles(MyAvatar.orientation).y;
+    var accumulatedRotation = 0;
+    function tick() {
+        MyAvatar.orientation = Quat.fromPitchYawRollDegrees(0, accumulatedRotation + initialRotation, 0);
+        if (strafeDistance) {
+            MyAvatar.position = Vec3.sum(MyAvatar.position, Vec3.multiply(strafeDistance, Quat.getRight(MyAvatar.orientation)));
+        }
+        accumulatedRotation += degreesPerUpdate;
+        if (accumulatedRotation >= targetRotation) {
+            return optionalCallback && optionalCallback();
+        }
+        Script.setTimeout(tick, interval);
+    }
+    tick();
+}
+
+function doLoad(place, continuationWithLoadTime) { // Go to place and call continuationWithLoadTime(loadTimeInSeconds)
+    var start = Date.now(), timeout, onDownloadUpdate, finishedTwirl = false, loadTime;
+    // There are two ways to learn of changes: connect to change signals, or poll.
+    // Until we get reliable results, we'll poll.
+    var POLL_INTERVAL = 500, poll;
+    function setHandlers() {
+        //Stats.downloadsPendingChanged.connect(onDownloadUpdate); downloadsChanged, and physics...
+        poll = Script.setInterval(onDownloadUpdate, POLL_INTERVAL);
+    }
+    function clearHandlers() {
+        debug('clearHandlers');
+        //Stats.downloadsPendingChanged.disconnect(onDownloadUpdate); downloadsChanged, and physics..
+        Script.clearInterval(poll);
+    }
+    function waitForLoad(flag) {
+        debug('entry', place, 'initial downloads/pending', Stats.downloads, Stats.downloadsPending);
+        location.hostChanged.disconnect(waitForLoad);
+        timeout = Script.setTimeout(function () {
+            debug('downloads timeout', Date());
+            clearHandlers();
+            Window.alert("Timeout during " + place + " load. FAILED");
+            Script.stop();
+        }, MAXIMUM_LOAD_TIME * 1000);
+        startTwirl(360, 6, 90, null, function () {
+            finishedTwirl = true;
+            if (loadTime) {
+                continuationWithLoadTime(loadTime);
+            }
+        });
+        setHandlers();
+    }
+    function isLoading() {
+        // FIXME: We should also confirm that textures have loaded.
+        return Stats.downloads || Stats.downloadsPending || !Window.isPhysicsEnabled();
+    }
+    onDownloadUpdate = function onDownloadUpdate() {
+        debug('update downloads/pending', Stats.downloads, Stats.downloadsPending);
+        if (isLoading()) {
+            return;
+        }
+        Script.clearTimeout(timeout);
+        clearHandlers();
+        loadTime = (Date.now() - start) / 1000;
+        if (finishedTwirl) {
+            continuationWithLoadTime(loadTime);
+        }
+    };
+
+    location.hostChanged.connect(waitForLoad);
+    go(place);
+}
+
+var config = Render.getConfig("Stats");
+function doRender(continuation) {
+    var start = Date.now(), frames = 0;
+    function onNewStats() { // Accumulates frames on signal during load test
+        frames++;
+    }
+    if (MINIMUM_AVATARS) {
+        messageSend({key: 'HELO'}); // Ask agents to report in now.
+    }
+
+    config.newStats.connect(onNewStats);
+    startTwirl(720, 1, 20, 0.08, function () {
+        var end = Date.now();
+        config.newStats.disconnect(onNewStats);
+        addResult('frame rate', 1000 * frames / (end - start),
+                  HMD.active ? EXPECTED_HMD_FRAMERATE : EXPECTED_DESKTOP_FRAMERATE,
+                  HMD.active ? MINIMUM_HMD_FRAMERATE : MINIMUM_DESKTOP_FRAMERATE);
+        var total = AvatarList.getAvatarIdentifiers().length;
+        if (MINIMUM_AVATARS && !fail) {
+            if (0 === summonedAgents.length) {
+                fail = "FAIL: No agents reported.\nPlease run " + MINIMUM_AVATARS + " instances of\n\
+http://hifi-content.s3.amazonaws.com/howard/scripts/tests/performance/crowd-agent.js?v=3\n\
+on your domain server.";
+            } else if (total < MINIMUM_AVATARS) {
+                fail = "FAIL: Only " + summonedAgents.length + " agents reported. Now missing " + (MINIMUM_AVATARS - total) + " avatars, total.";
+            }
+        }
+        continuation();
+    });
+}
+
+var TELEPORT_PAUSE = 500;
+function prepareCache(continuation) {
+    function loadNext() {
+        var place = cachePlaces.shift();
+        doLoad(place, function (prepTime) {
+            debug(place, 'ready', prepTime);
+            if (cachePlaces.length) {
+                loadNext();
+            } else {
+                continuation();
+            }
+        });
+    }
+    // remove entryPlace target from cachePlaces
+    var targetInCache = cachePlaces.indexOf(canonicalizePlacename(entryPlace));
+    if (targetInCache !== -1) {
+        cachePlaces.splice(targetInCache, 1);
+    }
+    debug('cachePlaces', cachePlaces);
+    go(cachePlaces[1] || entryPlace); // Not quite right for entryPlace case (allows some qt pre-caching), but close enough.
+    Script.setTimeout(function () {
+        Menu.triggerOption("Reload Content (Clears all caches)");
+        Script.setTimeout(loadNext, TELEPORT_PAUSE);
+    }, TELEPORT_PAUSE);
+}
+
+function maybeRunTribbles(continuation) {
+    if (runTribbles) {
+        Script.load('http://cdn.highfidelity.com/davidkelly/production/scripts/tests/performance/tribbles.js');
+        Script.setTimeout(continuation, 3000);
+    } else {
+        continuation();
+    }
+}
+
+if (!entryPlace) {
+    Window.alert("domain-check.js cancelled");
+    Script.stop();
+} else {
+    prepareCache(function (prepTime) {
+        debug('cache ready', prepTime);
+        doLoad(entryPlace, function (loadTime) {
+            addResult("load time", loadTime, NOMINAL_LOAD_TIME, undefined, MAXIMUM_LOAD_TIME);
+            LODManager.setAutomaticLODAdjust(initialLodIsAutomatic); // after loading, restore lod.
+            maybeRunTribbles(function () {
+                doRender(function () {
+                    giveReport();
+                    Script.stop();
+                });
+            });
+        });
+    });
+}
+
+Script.scriptEnding.connect(function () { print("domain-check completed"); });
diff --git a/hifi-content/howard/scripts/tests/performance/screamingAvatarAC.js b/hifi-content/howard/scripts/tests/performance/screamingAvatarAC.js
new file mode 100644
index 000000000..40210ef02
--- /dev/null
+++ b/hifi-content/howard/scripts/tests/performance/screamingAvatarAC.js
@@ -0,0 +1,39 @@
+var sound = SoundCache.getSound("http://hifi-content.s3.amazonaws.com/howard/sounds/piano1.wav");
+
+var ANIMATION_URL = "http://hifi-content.s3.amazonaws.com/howard/resources/avatar/animations/idle.fbx";
+var AVATAR_MODEL = "http://hifi-content.s3.amazonaws.com/howard/resources/meshes/defaultAvatar_full.fst";
+var POLL_INTERVAL = 500; // ms
+var SPREAD_MAX = 2;
+var SPREAD_MIN = 0;
+var SOUND_PAUSE_MAX = 10000;
+var SOUND_PAUSE_MIN = 2000;
+
+function randInterval(min, max) {
+    return min + Math.random()*(max-min);
+}
+
+Agent.isAvatar = true;
+Agent.isListening = true;
+
+Avatar.skeletonModelURL = AVATAR_MODEL;
+Avatar.position = { x: randInterval(SPREAD_MIN, SPREAD_MAX),
+                    y: randInterval(SPREAD_MIN, SPREAD_MAX),
+                    z: randInterval(SPREAD_MIN, SPREAD_MAX)
+};
+
+Avatar.startAnimation(ANIMATION_URL, 30, 1.0, true, false, 0, 300);
+
+var soundInterval = Script.setInterval(function () {
+    if (sound.downloaded) {
+        Script.clearInterval(soundInterval);
+        print("sound downloaded");
+        // now play it in a loop until the end of time
+        Script.setInterval(function() {
+            print("playing sound");
+            Agent.playAvatarSound(sound);
+        }, sound.duration + randInterval(SOUND_PAUSE_MIN, SOUND_PAUSE_MAX));
+    } else {
+        print("waiting for sound to download...");
+    }
+}, POLL_INTERVAL);
+
diff --git a/hifi-content/howard/scripts/tests/performance/summon.js b/hifi-content/howard/scripts/tests/performance/summon.js
new file mode 100644
index 000000000..29b61bf2c
--- /dev/null
+++ b/hifi-content/howard/scripts/tests/performance/summon.js
@@ -0,0 +1,157 @@
+"use strict";
+/*jslint vars: true, plusplus: true*/
+/*global Agent, Avatar, Script, Entities, Vec3, Quat, print*/
+//
+//  crowd-agent.js
+//  scripts/developer/tests/performance/
+//
+//  Created by Howard Stearns on 9/29/16.
+//  Copyright 2016 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+// See crowd-agent.js
+
+var version = 3;
+var label = "summon";
+function debug() {
+    print.apply(null, [].concat.apply([label, version], [].map.call(arguments, JSON.stringify)));
+}
+
+var MINIMUM_AVATARS = 25; // We will summon agents to produce this many total. (Of course, there might not be enough agents.)
+var N_LISTENING = MINIMUM_AVATARS - 1;
+var AVATARS_CHATTERING_AT_ONCE = 4; // How many of the agents should we request to play SOUND_DATA at once.
+
+var initialBubble = Users.getIgnoreRadiusEnabled();
+debug('startup seeking:', MINIMUM_AVATARS, 'listening:', N_LISTENING, 'chattering:', AVATARS_CHATTERING_AT_ONCE, 'had bubble:', initialBubble);
+
+// If we add or remove things too quickly, we get problems (e.g., audio, fogbugz 2095).
+// For now, spread them out this timing apart.
+var SPREAD_TIME_MS = 500;
+
+var DENSITY = 0.3; // square meters per person. Some say 10 sq ft is arm's length (0.9m^2), 4.5 is crowd (0.4m^2), 2.5 is mosh pit (0.2m^2).
+var SOUND_DATA = {url: "http://hifi-content.s3.amazonaws.com/howard/sounds/piano1.wav"};
+var NEXT_SOUND_SPREAD = 500; // millisecond range of how long to wait after one sound finishes, before playing the next
+var ANIMATION_DATA = {
+    "url": "http://hifi-content.s3.amazonaws.com/howard/resources/avatar/animations/idle.fbx",
+    // "url": "http://hifi-content.s3.amazonaws.com/howard/resources/avatar/animations/walk_fwd.fbx", // alternative example
+    "startFrame": 0.0,
+    "endFrame": 300.0,
+    "timeScale": 1.0,
+    "loopFlag": true
+};
+
+var spread = Math.sqrt(MINIMUM_AVATARS * DENSITY); // meters
+var turnSpread = 90; // How many degrees should turn from front range over.
+
+function coord() { return (Math.random() * spread) - (spread / 2); }  // randomly distribute a coordinate zero += spread/2.
+function contains(array, item) { return array.indexOf(item) >= 0; }
+function without(array, itemsToRemove) { return array.filter(function (item) { return !contains(itemsToRemove, item); }); }
+function nextAfter(array, id) { // Wrapping next element in array after id.
+    var index = array.indexOf(id) + 1;
+    return array[(index >= array.length) ? 0 : index];
+}
+
+var summonedAgents = [];
+var chattering = [];
+var nListening = 0;
+var accumulatedDelay = 0;
+var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd";
+function messageSend(message) {
+    Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message));
+}
+function messageHandler(channel, messageString, senderID) {
+    if (channel !== MESSAGE_CHANNEL) {
+        return;
+    }
+    debug('message', channel, messageString, senderID);
+    if (MyAvatar.sessionUUID === senderID) { // ignore my own
+        return;
+    }
+    var message = {};
+    try {
+        message = JSON.parse(messageString);
+    } catch (e) {
+        print(e);
+    }
+    switch (message.key) {
+    case "hello":
+        Script.setTimeout(function () {
+            // There can be avatars we've summoned that do not yet appear in the AvatarList.
+            var avatarIdentifiers = without(AvatarList.getAvatarIdentifiers(), summonedAgents);
+            var nSummoned = summonedAgents.length;
+            debug('present', avatarIdentifiers, summonedAgents);
+            if ((nSummoned + avatarIdentifiers.length) < MINIMUM_AVATARS ) {
+                var chatter = chattering.length < AVATARS_CHATTERING_AT_ONCE;
+                var listen = nListening < N_LISTENING;
+                if (chatter) {
+                    chattering.push(senderID);
+                }
+                if (listen) {
+                    nListening++;
+                }
+                summonedAgents.push(senderID);
+                messageSend({
+                    key: 'SUMMON',
+                    rcpt: senderID,
+                    displayName: "crowd " + nSummoned + " " + senderID,
+                    position: Vec3.sum(MyAvatar.position, {x: coord(), y: 0, z: coord()}),
+                    orientation: Quat.fromPitchYawRollDegrees(0, Quat.safeEulerAngles(MyAvatar.orientation).y + (turnSpread * (Math.random() - 0.5)), 0),
+                    soundData: chatter && SOUND_DATA,
+                    listen: listen,
+                    skeletonModelURL: "http://hifi-content.s3.amazonaws.com/howard/resources/meshes/defaultAvatar_full.fst",
+                    animationData: ANIMATION_DATA
+                });
+            }
+        }, accumulatedDelay);
+        accumulatedDelay += SPREAD_TIME_MS; // assume we'll get all the hello responses more or less together.
+        break;
+    case "finishedSound": // Give someone else a chance.
+        chattering = without(chattering, [senderID]);
+        Script.setTimeout(function () {
+            messageSend({
+                key: 'SUMMON',
+                rcpt: nextAfter(without(summonedAgents, chattering), senderID),
+                soundData: SOUND_DATA
+            });
+        }, Math.random() * NEXT_SOUND_SPREAD);
+        break;
+    case "HELO":
+        Window.alert("Someone else is summoning avatars.");
+        break;
+    default:
+        print("crowd summon.js received unrecognized message:", messageString);
+    }
+}
+Messages.subscribe(MESSAGE_CHANNEL);
+Messages.messageReceived.connect(messageHandler);
+Script.scriptEnding.connect(function () {
+    debug('stopping agents', summonedAgents);
+    Users.requestsDomainListData = false;
+    if (initialBubble && !Users.getIgnoreRadiusEnabled()) { Users.toggleIgnoreRadius(); }
+    Messages.messageReceived.disconnect(messageHandler); // don't respond to any messages during shutdown
+    accumulatedDelay = 0;
+    summonedAgents.forEach(function (id) {
+        messageSend({key: 'STOP', rcpt: id, delay: accumulatedDelay});
+        accumulatedDelay += SPREAD_TIME_MS;
+    }); 
+    debug('agents stopped');
+    Messages.unsubscribe(MESSAGE_CHANNEL);
+    debug('unsubscribed');
+});
+
+Users.requestsDomainListData = true; // Get avatar data for the whole domain, even if not in our view.
+if (initialBubble) { Users.toggleIgnoreRadius(); }
+messageSend({key: 'HELO'}); // Ask agents to report in now.
+Script.setTimeout(function () {
+    var total = AvatarList.getAvatarIdentifiers().length;
+    if (0 === summonedAgents.length) {
+        Window.alert("No agents reported.\n\Please run " + MINIMUM_AVATARS + " instances of\n\
+http://hifi-content.s3.amazonaws.com/howard/scripts/tests/performance/crowd-agent.js?v=someDate\n\
+on your domain server.");
+    } else if (total < MINIMUM_AVATARS) {
+        Window.alert("Only " + summonedAgents.length + " agents reported. Now missing " + (MINIMUM_AVATARS - total) + " avatars, total.");
+    }
+    Users.requestsDomainListData = false;
+}, MINIMUM_AVATARS * SPREAD_TIME_MS )
diff --git a/hifi-content/howard/sounds/hello.wav b/hifi-content/howard/sounds/hello.wav
new file mode 100644
index 000000000..a995e7d65
--- /dev/null
+++ b/hifi-content/howard/sounds/hello.wav
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6bbd7c78a54c8b62d509c102301a2c4647d4450abe314b2c3f869d755bdfacf9
+size 231196
diff --git a/hifi-content/howard/sounds/piano1.wav b/hifi-content/howard/sounds/piano1.wav
new file mode 100644
index 000000000..57de26dcf
--- /dev/null
+++ b/hifi-content/howard/sounds/piano1.wav
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f0c3614f197c953bf2abfddfd262ede87b94d195afb4d5a32aa1bcbbee5e38a0
+size 605468
diff --git a/hifi-content/howard/zaru-content-custom-scripts.zip b/hifi-content/howard/zaru-content-custom-scripts.zip
new file mode 100644
index 000000000..35ccca50a
--- /dev/null
+++ b/hifi-content/howard/zaru-content-custom-scripts.zip
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3afc07ec2d54a3e4f8d4c63a2348c98319184bf20ab0b14eea1e6cf183b248c4
+size 57483884
diff --git a/hifi-content/howard/zaru-content-default-scripts.zip b/hifi-content/howard/zaru-content-default-scripts.zip
new file mode 100644
index 000000000..d16b101b9
--- /dev/null
+++ b/hifi-content/howard/zaru-content-default-scripts.zip
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:66cc1ca2df52b52db588d3a0b27d75a478648a5a4f3bbdea1905edbddef36563
+size 57483371
diff --git a/hifi-content/howell/Prototypes/Cartoony_Computer/CCTV_image-redigert.jpg b/hifi-content/howell/Prototypes/Cartoony_Computer/CCTV_image-redigert.jpg
new file mode 100644
index 000000000..31cbf3738
--- /dev/null
+++ b/hifi-content/howell/Prototypes/Cartoony_Computer/CCTV_image-redigert.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:90f6c2a8798894aaa28d56638ea63e0beed0baf83bc76876046cc3c1cc52179c
+size 554614
diff --git a/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.FBX b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.FBX
new file mode 100644
index 000000000..75593922e
--- /dev/null
+++ b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.FBX
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2c975e55ed89259df4ec3ea70a6cab91d10b5dacb705c6de7f2fb60b211324fc
+size 536048
diff --git a/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.max b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.max
new file mode 100644
index 000000000..8f8340149
--- /dev/null
+++ b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.max
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:443d4bc32914392ae60cf9eb5dae38188b3fc3afb5fd23601d03b489520894e2
+size 1925120
diff --git a/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.mtl b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.mtl
new file mode 100644
index 000000000..914a843e5
--- /dev/null
+++ b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.mtl
@@ -0,0 +1,84 @@
+# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
+# File Created: 19.03.2013 20:37:19
+
+newmtl Material__223
+	Ns 10.0000
+	Ni 1.5000
+	d 1.0000
+	Tr 0.0000
+	Tf 1.0000 1.0000 1.0000 
+	illum 2
+	Ka 0.5880 0.5880 0.5880
+	Kd 0.7765 0.7765 0.7765
+	Ks 0.0000 0.0000 0.0000
+	Ke 0.0000 0.0000 0.0000
+
+newmtl CCTV_screen
+	Ns 10.0000
+	Ni 1.5000
+	d 1.0000
+	Tr 0.0000
+	Tf 1.0000 1.0000 1.0000 
+	illum 2
+	Ka 0.5880 0.5880 0.5880
+	Kd 0.1137 0.1137 0.1137
+	Ks 0.0000 0.0000 0.0000
+	Ke 0.0978 0.0978 0.0978
+	map_Ka F:\shared\TurboSquid\Free\Computer\maps\CCTV_image-redigert.jpg
+	map_Kd F:\shared\TurboSquid\Free\Computer\maps\CCTV_image-redigert.jpg
+
+newmtl Material__225
+	Ns 10.0000
+	Ni 1.5000
+	d 1.0000
+	Tr 0.0000
+	Tf 1.0000 1.0000 1.0000 
+	illum 2
+	Ka 0.5880 0.5880 0.5880
+	Kd 0.4275 0.4275 0.4275
+	Ks 0.0000 0.0000 0.0000
+	Ke 0.0000 0.0000 0.0000
+
+newmtl Computer_screen
+	Ns 10.0000
+	Ni 1.5000
+	d 1.0000
+	Tr 0.0000
+	Tf 1.0000 1.0000 1.0000 
+	illum 2
+	Ka 0.5880 0.5880 0.5880
+	Kd 0.8784 0.8549 0.8118
+	Ks 0.0000 0.0000 0.0000
+	Ke 0.0000 0.0000 0.0000
+
+newmtl wire_154215229
+	Ns 32
+	d 1
+	Tr 0
+	Tf 1 1 1
+	illum 2
+	Ka 0.6039 0.8431 0.8980
+	Kd 0.6039 0.8431 0.8980
+	Ks 0.3500 0.3500 0.3500
+
+newmtl wire_177088027
+	Ns 32
+	d 1
+	Tr 0
+	Tf 1 1 1
+	illum 2
+	Ka 0.6941 0.3451 0.1059
+	Kd 0.6941 0.3451 0.1059
+	Ks 0.3500 0.3500 0.3500
+
+newmtl RedButton
+	Ns 10.0000
+	Ni 1.5000
+	d 1.0000
+	Tr 0.0000
+	Tf 1.0000 1.0000 1.0000 
+	illum 2
+	Ka 0.5880 0.5880 0.5880
+	Kd 1.0000 0.0000 0.0000
+	Ks 0.0000 0.0000 0.0000
+	Ke 0.0000 0.0000 0.0000
diff --git a/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.obj b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.obj
new file mode 100644
index 000000000..8ce0e9c4f
--- /dev/null
+++ b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.obj
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c62744991df8b49dfe081027be0aacbc066864f401e4d15fd0845d3026de3cbc
+size 952242
diff --git a/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer[max2010].max b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer[max2010].max
new file mode 100644
index 000000000..63454eedd
--- /dev/null
+++ b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer[max2010].max
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:950ac518d51b84869f080e6c7c14d62f181475b6ef7422d5520e3574a77777e5
+size 1761280
diff --git a/hifi-content/howell/Prototypes/GOT/GOT.png b/hifi-content/howell/Prototypes/GOT/GOT.png
new file mode 100644
index 000000000..baf7e0353
--- /dev/null
+++ b/hifi-content/howell/Prototypes/GOT/GOT.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e85deb385b86801c5c5cf0dccafa187c3cc1d9c84b3f8d515e0ca2ac588b747f
+size 98997
diff --git a/hifi-content/howell/Prototypes/GOT/drogon finished with base2.obj b/hifi-content/howell/Prototypes/GOT/drogon finished with base2.obj
new file mode 100644
index 000000000..8be9a77bc
--- /dev/null
+++ b/hifi-content/howell/Prototypes/GOT/drogon finished with base2.obj	
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ceaa61bde404e2621e5ddbcbbf18224fc1a4d1207093bb5dca55b75c46e7d47d
+size 30302889
diff --git a/hifi-content/howell/Prototypes/GOT/drogon-statue.fbx b/hifi-content/howell/Prototypes/GOT/drogon-statue.fbx
new file mode 100644
index 000000000..8ac488408
--- /dev/null
+++ b/hifi-content/howell/Prototypes/GOT/drogon-statue.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:df2e239a3abb3797ece2ddfaca17e7103f0d14aeaa1969d657a474545e0f411c
+size 17763132
diff --git a/hifi-content/howell/Prototypes/Idle_app/Hanging Idle.fbx b/hifi-content/howell/Prototypes/Idle_app/Hanging Idle.fbx
new file mode 100644
index 000000000..7643ae8c6
--- /dev/null
+++ b/hifi-content/howell/Prototypes/Idle_app/Hanging Idle.fbx	
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:93019adf0763112f7082d6e1475f2c4f09f7c34fc3f02fd052cd772935f6b5df
+size 439568
diff --git a/hifi-content/howell/Prototypes/Idle_app/Happy.fbx b/hifi-content/howell/Prototypes/Idle_app/Happy.fbx
new file mode 100644
index 000000000..e5356ea7f
--- /dev/null
+++ b/hifi-content/howell/Prototypes/Idle_app/Happy.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b9c35753b396373d6646521a69bbca9b9bc8d4e24992925ffdc1941b07c2c9f1
+size 531520
diff --git a/hifi-content/howell/Prototypes/Idle_app/Male Laying Pose.fbx b/hifi-content/howell/Prototypes/Idle_app/Male Laying Pose.fbx
new file mode 100644
index 000000000..28395a95f
--- /dev/null
+++ b/hifi-content/howell/Prototypes/Idle_app/Male Laying Pose.fbx	
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fb9e60eef42c9c5144fd419c8eb00c8c8a79be1dd18ae91ffe9e65383973d725
+size 210944
diff --git a/hifi-content/howell/Prototypes/Idle_app/Ninja Idle.fbx b/hifi-content/howell/Prototypes/Idle_app/Ninja Idle.fbx
new file mode 100644
index 000000000..9d7887e20
--- /dev/null
+++ b/hifi-content/howell/Prototypes/Idle_app/Ninja Idle.fbx	
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a580d6c309a0fa3fe1ddba1f41c60693c2573f4203026945cbe583972cad836e
+size 652512
diff --git a/hifi-content/howell/Prototypes/Idle_app/Push Up.fbx b/hifi-content/howell/Prototypes/Idle_app/Push Up.fbx
new file mode 100644
index 000000000..c14ddde70
--- /dev/null
+++ b/hifi-content/howell/Prototypes/Idle_app/Push Up.fbx	
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2828190ed38048d7387a169b3f34ecf4a34a0830527c062590326dd63767bf96
+size 331072
diff --git a/hifi-content/howell/Prototypes/Idle_app/mat_laying.fbx b/hifi-content/howell/Prototypes/Idle_app/mat_laying.fbx
new file mode 100644
index 000000000..f17e21e54
--- /dev/null
+++ b/hifi-content/howell/Prototypes/Idle_app/mat_laying.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:82be489c57ba5f8ccc90f4fde4214b980cb28e4b610888ea5ff456ed7ebc15b2
+size 210944
diff --git a/hifi-content/howell/Prototypes/JAT_test/JATScritp.js b/hifi-content/howell/Prototypes/JAT_test/JATScritp.js
new file mode 100644
index 000000000..6cded211d
--- /dev/null
+++ b/hifi-content/howell/Prototypes/JAT_test/JATScritp.js
@@ -0,0 +1,344 @@
+//
+//  JATAvatarScript.js
+//
+// Rezzes JAT's avatars as Overlays, and handle clicking on them.
+//
+//  Created by Zach Fox on 2019-03-15
+//  Copyright 2019 High Fidelity, Inc.
+//
+//  See accompanying README.md for usage instructions.
+// 
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+
+
+(function () {
+    var BASE_RELATIVE_POSITION = {"x":20.9303035736084,"y":-11.449395179748535,"z":-50.0930061340332};
+
+    var config = Script.require(Script.resolvePath("config.json?" + Date.now()));
+
+    var AVATAR_OVERLAY_PROPERTIES = [
+        {
+            "type": "Model",
+            "name": config.avatars[0].name,
+            "position": {
+                "x": 0.8213138580322266,
+                "y": 0.022147178649902344,
+                "z": 0.5046806335449219
+            },
+            "dimensions": {
+                "x": 0.4687473773956299,
+                "y": 0.797889769077301,
+                "z": 0.3429218530654907
+            },
+            "rotation": {
+                "x": -0.0000457763671875,
+                "y": -0.2866712212562561,
+                "z": -0.0000152587890625,
+                "w": 0.9580377340316772
+            },
+            "url": config.avatars[0].url,
+            "isFacingAvatar": false
+        },
+        {
+            "id": "{d8ad1d89-038e-43c2-87dc-6d38988a71a4}",
+            "type": "Model",
+            "name": config.avatars[1].name,
+            "position": {
+                "x": 2.492778778076172,
+                "y": 0.08696365356445312,
+                "z": 2.8273887634277344
+            },
+            "dimensions": {
+                "x": 0.5626906156539917,
+                "y": 0.9782152771949768,
+                "z": 0.20142969489097595
+            },
+            "rotation": {
+                "x": 0.0000152587890625,
+                "y": 0.5656976699829102,
+                "z": -0.0000457763671875,
+                "w": -0.8246127963066101
+            },
+            "url": config.avatars[1].url,
+            "isFacingAvatar": false
+        },
+        {
+            "id": "{ac2a7754-eec7-4bb6-9550-3af9caa970c9}",
+            "type": "Model",
+            "name": config.avatars[2].name,
+            "position": {
+                "x": 1.6198616027832031,
+                "y": 0.17209148406982422,
+                "z": 1.1371917724609375
+            },
+            "dimensions": {
+                "x": 1.1117140054702759,
+                "y": 0.8896834254264832,
+                "z": 0.6230975985527039
+            },
+            "rotation": {
+                "x": -0.0000457763671875,
+                "y": -0.423941433429718,
+                "z": -0.0000457763671875,
+                "w": 0.9056992530822754
+            },
+            "url": config.avatars[2].url,
+            "isFacingAvatar": false
+        },
+        {
+            "id": "{0b261ed8-4c78-40db-915d-951b819821f5}",
+            "type": "Model",
+            "name": config.avatars[3].name,
+            "position": {
+                "x": 0,
+                "y": 0.12828731536865234,
+                "z": 0
+            },
+            "dimensions": {
+                "x": 1.0574196577072144,
+                "y": 1.1382946968078613,
+                "z": 0.27917155623435974
+            },
+            "rotation": {
+                "x": -0.0000457763671875,
+                "y": -0.22655069828033447,
+                "z": -0.0000152587890625,
+                "w": 0.9739986658096313
+            },
+            "url": config.avatars[3].url,
+            "isFacingAvatar": false
+        },
+        {
+            "id": "{57168289-d40e-467a-8154-c9f1c6868615}",
+            "type": "Model",
+            "name": config.avatars[4].name,
+            "position": {
+                "x": 2.1323165893554688,
+                "y": 0,
+                "z": 2.091522216796875
+            },
+            "dimensions": {
+                "x": 0.667604386806488,
+                "y": 0.8386905193328857,
+                "z": 0.1569727063179016
+            },
+            "rotation": {
+                "x": 0.0000152587890625,
+                "y": 0.5126268863677979,
+                "z": -0.0000762939453125,
+                "w": -0.8586099147796631
+            },
+            "url": config.avatars[4].url,
+            "isFacingAvatar": false
+        }
+    ];
+
+    var BUTTON_DIMENSIONS = {"x": 0.2, "y": 0.2, "z": 0.2};
+    var BUTTON_ROTATION = Quat.fromPitchYawRollDegrees(180, 140, 180);
+    var BUTTON_ROTATION_PREV = Quat.fromPitchYawRollDegrees(180, -140, 0);
+
+    var CONTROL_BUTTON_PROPERTIES = [
+        {
+            "name": "play",
+            "url": "https://hifi-content.s3.amazonaws.com/alan/dev/playback_play-button.fbx",
+            "position": {
+                "x": 16.6961,
+                "y": -11.1147,
+                "z": -48.6680
+            },
+            "dimensions": BUTTON_DIMENSIONS,
+            "rotation": BUTTON_ROTATION
+        },
+        {
+            "name": "pause",
+            "url": "https://hifi-content.s3.amazonaws.com/alan/dev/playback_pause-button.fbx",
+            "position": {
+                "x": 17.1057,
+                "y": -11.1149,
+                "z": -48.9547
+            },
+            "dimensions": BUTTON_DIMENSIONS,
+            "rotation": BUTTON_ROTATION
+        },
+        {
+            "name": "previous",
+            "url": "https://hifi-content.s3.amazonaws.com/alan/dev/playback_ff-rw-button.fbx",
+            "position": {
+                "x": 17.5153,
+                "y": -11.1150,
+                "z": -49.2414
+            },
+            "dimensions": BUTTON_DIMENSIONS,
+            "rotation": BUTTON_ROTATION_PREV
+        },
+        {
+            "name": "next",
+            "url": "https://hifi-content.s3.amazonaws.com/alan/dev/playback_ff-rw-button.fbx",
+            "position": {
+                "x": 17.9249,
+                "y": -11.1151,
+                "z": -49.5279
+            },
+            "dimensions": BUTTON_DIMENSIONS,
+            "rotation": BUTTON_ROTATION
+        }
+    ];
+
+    var TEXT_OVERLAY_PROPERTIES = {
+        "name": "text",
+        "lineHeight": 0.10,
+        "backgroundAlpha": 0.75,
+        "position": {
+            "x": 15.7621,
+            "y": -11.3145,
+            "z": -48.2583
+        },
+        "rotation": BUTTON_ROTATION,
+        "dimensions": {
+            "x": 1.5,
+            "y": 0.25,
+            "z": 1
+        },
+        "topMargin": 0,
+        "rightMargin": 0,
+        "bottomMargin": 0,
+        "leftMargin": 0
+    };
+
+    var METERS_TO_INCHES = 39.3701;
+    var WEB_OVERLAY_PROPERTIES = {
+        "rotation": BUTTON_ROTATION,
+        "dimensions": {
+            "x": 1,
+            "y": 1,
+            "z": 0
+        },
+        "position": {
+            "x": 18.8594,
+            "y": -11.3154,
+            "z": -50.4261
+        },
+        "url": config.screenleapURL,
+        "dpi": 1920 / (3 * METERS_TO_INCHES),
+        "alpha": 0.75
+    };
+
+    var rezzedAvatarOverlays = [];
+    function rezAvatarOverlays() {
+        for (var i = 0; i < AVATAR_OVERLAY_PROPERTIES.length; i++) {
+            var currentProps = AVATAR_OVERLAY_PROPERTIES[i];
+            currentProps.position = Vec3.sum(currentProps.position, BASE_RELATIVE_POSITION);
+            console.log("Rezzing overlay with name " +
+                AVATAR_OVERLAY_PROPERTIES[i].name + " at " + JSON.stringify(currentProps.position));
+            rezzedAvatarOverlays.push(Overlays.addOverlay("model", currentProps));
+        }
+    }
+
+    var rezzedControlButtonOverlays = [];
+    function rezVideoControlButtons() {
+        for (var i = 0; i < CONTROL_BUTTON_PROPERTIES.length; i++) {
+            var currentProps = CONTROL_BUTTON_PROPERTIES[i];
+            console.log("Rezzing overlay with name " +
+                CONTROL_BUTTON_PROPERTIES[i].name + " at " + JSON.stringify(currentProps.position));
+            rezzedControlButtonOverlays.push(Overlays.addOverlay("model", currentProps));
+        }
+    }
+
+    var textOverlay = false;
+    function rezTextOverlay() {
+        console.log("Rezzing overlay with name " +
+            TEXT_OVERLAY_PROPERTIES.name + " at " + JSON.stringify(TEXT_OVERLAY_PROPERTIES.position));
+        textOverlay = Overlays.addOverlay("text3d", TEXT_OVERLAY_PROPERTIES);
+    }
+
+    var webOverlay = false;
+    function rezWebOverlay() {
+        console.log("Rezzing overlay with name " +
+        WEB_OVERLAY_PROPERTIES.name + " at " + JSON.stringify(WEB_OVERLAY_PROPERTIES.position));
+        webOverlay = Overlays.addOverlay("web3d", WEB_OVERLAY_PROPERTIES);
+    }
+
+    function startup() {
+        console.log("Welcome to rezJATAvatars.js!");
+    
+        rezAvatarOverlays();
+        rezVideoControlButtons();
+        rezTextOverlay();
+        rezWebOverlay();
+    }
+
+    function onScriptEnding() {
+        for (var i = 0; i < rezzedAvatarOverlays.length; i++) {
+            console.log("Deleting local entity with ID " + rezzedAvatarOverlays[i]);
+            Overlays.deleteOverlay(rezzedAvatarOverlays[i]);
+        }
+        for (i = 0; i < rezzedAvatarOverlays.length; i++) {
+            console.log("Deleting local entity with ID " + rezzedControlButtonOverlays[i]);
+            Overlays.deleteOverlay(rezzedControlButtonOverlays[i]);
+        }
+
+        if (textOverlay) {
+            Overlays.deleteOverlay(textOverlay);
+        }
+
+        if (webOverlay) {
+            Overlays.deleteOverlay(webOverlay);
+        }
+
+        Overlays.mousePressOnOverlay.disconnect(onMousePressOnOverlay);
+    }
+
+    var MESSAGE_CHANNEL = config.controlsMessageChannel;
+    function handleControlButtonPress(id) {
+        var name = Overlays.getProperties(id, ["name"]).name;
+
+        switch (name) {
+            case "play":
+                Messages.sendMessage(MESSAGE_CHANNEL, 'play');
+                break;
+
+            case "pause":
+                Messages.sendMessage(MESSAGE_CHANNEL, 'pause');
+                break;
+
+            case "previous":
+                Messages.sendMessage(MESSAGE_CHANNEL, 'previous');
+                break;
+
+            case "next":
+                Messages.sendMessage(MESSAGE_CHANNEL, 'next');
+                break;
+
+            default:
+                console.log("Unhandled button overlay pressed");
+        }
+    }
+
+    var STATUS_MESSAGE_CHANNEL = config.statusMessageChannel;
+    function onMessageReceived(channel, message) {
+        if (channel === STATUS_MESSAGE_CHANNEL && textOverlay){
+            console.log("message", message);
+            Overlays.editOverlay(textOverlay, {text: message});
+        }
+    }
+
+    function onMousePressOnOverlay(id, event) {
+        if (!event.button === "Primary") {
+            return;
+        }
+        
+        if (rezzedAvatarOverlays.indexOf(id) > -1) {
+            var modelURL = Overlays.getProperties(id, ["url"]).url;
+            MyAvatar.useFullAvatarURL(modelURL);
+        } else if (rezzedControlButtonOverlays.indexOf(id) > -1) {
+            handleControlButtonPress(id);
+        }
+    }
+
+    Overlays.mousePressOnOverlay.connect(onMousePressOnOverlay);
+    Script.scriptEnding.connect(onScriptEnding);
+    Messages.subscribe(STATUS_MESSAGE_CHANNEL);
+    Messages.messageReceived.connect(onMessageReceived);
+    startup();
+})();
diff --git a/hifi-content/howell/Prototypes/JAT_test/config.json b/hifi-content/howell/Prototypes/JAT_test/config.json
new file mode 100644
index 000000000..c587d53fe
--- /dev/null
+++ b/hifi-content/howell/Prototypes/JAT_test/config.json
@@ -0,0 +1,27 @@
+{
+    "avatars": [
+        {
+            "name": "Andy1",
+            "url": "https://raw.githubusercontent.com/AndySeattle/Avatar/master/office_zombie_alive/office_zombie_alive.fst"
+        },
+        {
+            "name": "Vacation",
+            "url": "https://raw.githubusercontent.com/AndySeattle/Avatar/master/Zombie_on_vacation/zombie_on_vacation_hifi.fst"
+        },
+        {
+            "name": "Ice Hero",
+            "url": "http://mpassets.highfidelity.com/e238153a-21f4-4eba-8ab5-c6b10a0eb967-v1/avatar.fst"
+        },
+        {
+            "name": "Ice Hero2",
+            "url": "http://mpassets.highfidelity.com/e238153a-21f4-4eba-8ab5-c6b10a0eb967-v1/avatar.fst"
+        },
+        {
+            "name": "ice hero 3",
+            "url": http://mpassets.highfidelity.com/e238153a-21f4-4eba-8ab5-c6b10a0eb967-v1/avatar.fst"
+        }
+    ],
+    "screenleapURL": "<URL to Screenleap associated with the Web Overlay that shows up in front of JAT>",
+    "controlsMessageChannel": "<Message channel used for presentation controls>",
+    "statusMessageChannel": "<Message channel used for changing presentation status text>"
+}
\ No newline at end of file
diff --git a/hifi-content/howell/Prototypes/andy_bot_bingos.js b/hifi-content/howell/Prototypes/andy_bot_bingos.js
new file mode 100644
index 000000000..6a435366d
--- /dev/null
+++ b/hifi-content/howell/Prototypes/andy_bot_bingos.js
@@ -0,0 +1,125 @@
+randFloat = function(low, high) {
+    return low + Math.random() * (high - low);
+}
+
+var baseURL = "https://hifi-content.s3.amazonaws.com/milad/ROLC/Organize/Projects/Testing/Flow/out/hfr/";
+
+// Link to get the urls from
+var GOOGLE_SHEET_URL = "https://script.googleusercontent.com/a/macros/highfidelity.io/echo?user_content_key=z30W_Z9rqfb41pGEoxCkUM9yv8ZN8mxWuMyDWUHroj3cJ65OTSWNE_Zq7wvrTybnnFtRp6azMkya2K4Hj_UvG2HA9j2tP4Hjm5_BxDlH2jW0nuo2oDemN9CCS2h10ox_nRPgeZU6HP_Ok_bZ6q4uc2IEwUGUhs3tubd_SaoYEJGc6Y4WQVrmGLClD6RzMAfZPxqtsdMQ32tpzl66ygAELl7JpluoKw78VudcD_Dja5DuJzk35EV1vQ&lib=MzB5vcFo1OT_VNOUwG7287OYoCQvnAuFY";
+var rand = 10000;
+var min = 2000;
+var timeoutPeriod = Math.floor(Math.random()*rand)+min;
+
+var sheetXHR;
+Script.setTimeout(function(){
+    //console.log("about to run XHR");
+    sheetXHR = new XHR(GOOGLE_SHEET_URL, sheetSuccess, sheetFailure);
+
+}, timeoutPeriod);
+var TABLE = [];
+var TOTAL_TO_GRAB = 100;
+
+function XHR(url, successCb, failureCb, TIMEOUT) {
+    //print("XHR: request url = " + url);
+    var self = this;
+    this.url = url;
+    this.successCb = successCb;
+    this.failureCb = failureCb;
+    this.req = new XMLHttpRequest();
+    this.req.open("GET", url, true);
+    this.req.timeout = TIMEOUT;
+    this.req.ontimeout = function () {
+        if (self.failureCb) {
+            self.failureCb(0, "timeout");
+        }
+    };
+    this.req.onreadystatechange = function () {
+        if (self.req.readyState === self.req.DONE) {
+            if (self.req.status === 200 || self.req.status === 203) {
+                if (self.successCb) {
+                    self.successCb(self.req.responseText);
+                }
+            } else {
+                if (self.failureCb) {
+                    self.failureCb(self.req.status, "done");
+                }
+            }
+        }
+    };
+    this.req.send();
+}
+
+function baseName(str) {
+    var base = new String(str).substring(str.lastIndexOf('/') + 1);
+    if (base.lastIndexOf(".") !== -1) {
+        base = base.substring(0, base.lastIndexOf("."));
+    }
+    return base;
+}
+
+function sheetFailure(status, reason) {
+    //console.log("sheetFailure status code = " + status + ", reason = " + reason);
+}
+
+function sheetSuccess(response) {
+    //console.log("sheetSuccess status, = ");
+    TABLE = JSON.parse(response);
+    TABLE.shift(); // strip off the header row.
+    for (var i = 0; i < TOTAL_TO_GRAB; i++){
+        TABLE.map(function(recording){
+            return baseName(TABLE[i].avatar_HFR);
+        }) 
+    }
+    
+    var randomIndex = Math.floor((Math.random() * TABLE.length) % TABLE.length);
+    var RECORDING_URL = TABLE[randomIndex].avatar_HFR;
+    
+    var LOCATIONS_ARRAY = [{ min_x: -88, max_x: -66, y: -21, min_z: 2.8, max_z: 10 }];
+
+    var LOCATION_PARAMS = LOCATIONS_ARRAY[Math.floor(Math.random() * LOCATIONS_ARRAY.length)];
+
+    var LOCATION = { x: randFloat(LOCATION_PARAMS.min_x, LOCATION_PARAMS.max_x), y: LOCATION_PARAMS.y, z: randFloat(LOCATION_PARAMS.min_z, LOCATION_PARAMS.max_z) };
+
+    //Vec3.print("RANDOM LOCATION SELECTED:", LOCATION);
+
+    // Disable the privacy bubble
+    Users.disableIgnoreRadius();
+
+    // Set position here if playFromCurrentLocation is true
+    Avatar.position = LOCATION;
+    Avatar.orientation = Quat.fromPitchYawRollDegrees(0, randFloat(0, 360), 0);
+    Avatar.scale = 1.0;
+    Agent.isAvatar = true;
+
+    Recording.loadRecording(RECORDING_URL, function(success) {
+        if (success) {
+            Script.update.connect(update);
+        } else {
+           // print("Failed to load recording from " + RECORDING_URL);
+        }
+    });
+}
+
+count = 300; // Randomly wait some period of time before starting the recording
+function update(event) {
+    if (count > 0) {
+        count--;
+        return;
+    }
+  
+    if (count == 0) {
+        Recording.setPlayFromCurrentLocation(true);
+        Recording.setPlayerLoop(true);
+        Recording.startPlaying();
+        //Vec3.print("Playing from ", Avatar.position);
+        count--;
+    }
+
+    EntityViewer.setPosition(Avatar.position);
+    EntityViewer.setOrientation(Avatar.orientation);
+    EntityViewer.queryOctree();
+
+    if (!Recording.isPlaying()) {
+        Script.update.disconnect(update);
+    }
+}
\ No newline at end of file
diff --git a/hifi-content/howell/Prototypes/andy_bots.js b/hifi-content/howell/Prototypes/andy_bots.js
new file mode 100644
index 000000000..4d0200259
--- /dev/null
+++ b/hifi-content/howell/Prototypes/andy_bots.js
@@ -0,0 +1,125 @@
+randFloat = function(low, high) {
+    return low + Math.random() * (high - low);
+}
+
+var baseURL = "https://hifi-content.s3.amazonaws.com/milad/ROLC/Organize/Projects/Testing/Flow/out/hfr/";
+
+// Link to get the urls from
+var GOOGLE_SHEET_URL = "https://script.googleusercontent.com/a/macros/highfidelity.io/echo?user_content_key=z30W_Z9rqfb41pGEoxCkUM9yv8ZN8mxWuMyDWUHroj3cJ65OTSWNE_Zq7wvrTybnnFtRp6azMkya2K4Hj_UvG2HA9j2tP4Hjm5_BxDlH2jW0nuo2oDemN9CCS2h10ox_nRPgeZU6HP_Ok_bZ6q4uc2IEwUGUhs3tubd_SaoYEJGc6Y4WQVrmGLClD6RzMAfZPxqtsdMQ32tpzl66ygAELl7JpluoKw78VudcD_Dja5DuJzk35EV1vQ&lib=MzB5vcFo1OT_VNOUwG7287OYoCQvnAuFY";
+var rand = 10000;
+var min = 2000;
+var timeoutPeriod = Math.floor(Math.random()*rand)+min;
+
+var sheetXHR;
+Script.setTimeout(function(){
+    //console.log("about to run XHR");
+    sheetXHR = new XHR(GOOGLE_SHEET_URL, sheetSuccess, sheetFailure);
+
+}, timeoutPeriod);
+var TABLE = [];
+var TOTAL_TO_GRAB = 100;
+
+function XHR(url, successCb, failureCb, TIMEOUT) {
+    //print("XHR: request url = " + url);
+    var self = this;
+    this.url = url;
+    this.successCb = successCb;
+    this.failureCb = failureCb;
+    this.req = new XMLHttpRequest();
+    this.req.open("GET", url, true);
+    this.req.timeout = TIMEOUT;
+    this.req.ontimeout = function () {
+        if (self.failureCb) {
+            self.failureCb(0, "timeout");
+        }
+    };
+    this.req.onreadystatechange = function () {
+        if (self.req.readyState === self.req.DONE) {
+            if (self.req.status === 200 || self.req.status === 203) {
+                if (self.successCb) {
+                    self.successCb(self.req.responseText);
+                }
+            } else {
+                if (self.failureCb) {
+                    self.failureCb(self.req.status, "done");
+                }
+            }
+        }
+    };
+    this.req.send();
+}
+
+function baseName(str) {
+    var base = new String(str).substring(str.lastIndexOf('/') + 1);
+    if (base.lastIndexOf(".") !== -1) {
+        base = base.substring(0, base.lastIndexOf("."));
+    }
+    return base;
+}
+
+function sheetFailure(status, reason) {
+    //console.log("sheetFailure status code = " + status + ", reason = " + reason);
+}
+
+function sheetSuccess(response) {
+    //console.log("sheetSuccess status, = ");
+    TABLE = JSON.parse(response);
+    TABLE.shift(); // strip off the header row.
+    for (var i = 0; i < TOTAL_TO_GRAB; i++){
+        TABLE.map(function(recording){
+            return baseName(TABLE[i].avatar_HFR);
+        }) 
+    }
+    
+    var randomIndex = Math.floor((Math.random() * TABLE.length) % TABLE.length);
+    var RECORDING_URL = TABLE[randomIndex].avatar_HFR;
+    
+    var LOCATIONS_ARRAY = [{ min_x: -6, max_x: 21, y: -12, min_z: -57, max_z: -54 }];
+
+    var LOCATION_PARAMS = LOCATIONS_ARRAY[Math.floor(Math.random() * LOCATIONS_ARRAY.length)];
+
+    var LOCATION = { x: randFloat(LOCATION_PARAMS.min_x, LOCATION_PARAMS.max_x), y: LOCATION_PARAMS.y, z: randFloat(LOCATION_PARAMS.min_z, LOCATION_PARAMS.max_z) };
+
+    //Vec3.print("RANDOM LOCATION SELECTED:", LOCATION);
+
+    // Disable the privacy bubble
+    Users.disableIgnoreRadius();
+
+    // Set position here if playFromCurrentLocation is true
+    Avatar.position = LOCATION;
+    Avatar.orientation = Quat.fromPitchYawRollDegrees(0, randFloat(0, 360), 0);
+    Avatar.scale = 1.0;
+    Agent.isAvatar = true;
+
+    Recording.loadRecording(RECORDING_URL, function(success) {
+        if (success) {
+            Script.update.connect(update);
+        } else {
+           // print("Failed to load recording from " + RECORDING_URL);
+        }
+    });
+}
+
+count = 300; // Randomly wait some period of time before starting the recording
+function update(event) {
+    if (count > 0) {
+        count--;
+        return;
+    }
+  
+    if (count == 0) {
+        Recording.setPlayFromCurrentLocation(true);
+        Recording.setPlayerLoop(true);
+        Recording.startPlaying();
+        //Vec3.print("Playing from ", Avatar.position);
+        count--;
+    }
+
+    EntityViewer.setPosition(Avatar.position);
+    EntityViewer.setOrientation(Avatar.orientation);
+    EntityViewer.queryOctree();
+
+    if (!Recording.isPlaying()) {
+        Script.update.disconnect(update);
+    }
+}
\ No newline at end of file
diff --git a/hifi-content/howell/Prototypes/andy_bots_futvrelands.js b/hifi-content/howell/Prototypes/andy_bots_futvrelands.js
new file mode 100644
index 000000000..4fb074a09
--- /dev/null
+++ b/hifi-content/howell/Prototypes/andy_bots_futvrelands.js
@@ -0,0 +1,203 @@
+//
+// BetterClientSimulationBotFromRecording.js
+//  examples
+//
+//  Created by Brad Hefta-Gaub on 2/6/17.
+//  Copyright 2017 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+
+var WANT_DEBUGGING = false;
+
+randFloat = function(low, high) {
+    return low + Math.random() * (high - low);
+}
+
+var MESSAGE_CHANNEL = "TriviaChannel";
+
+var AVATARS_ARRAY = [
+        "http://mpassets.highfidelity.com/0c2c264b-2fd2-46a4-bf80-de681881f66b-v1/F_MotRac.fst",
+        "http://mpassets.highfidelity.com/bd80a6d7-7173-489e-87c6-f7ee56e65530-v1/M_RetFut.fst",
+        "http://mpassets.highfidelity.com/47c8d706-d486-4c2d-afcc-70d4e1e25117-v1/M_RetSpaSuit.fst",
+        "http://mpassets.highfidelity.com/548d0792-0bac-4933-bbfc-57d71912d77e-v1/M_OutMer.fst",
+        "http://mpassets.highfidelity.com/13277c09-892f-4a5e-b9a5-8994a37d68bf-v1/F_WasWar.fst",
+        "http://mpassets.highfidelity.com/2d384111-0f0e-42e2-b800-66bfcab4aefb-v1/F_VooQue.fst",
+        "http://mpassets.highfidelity.com/57e4d1cd-9f52-4c95-9051-326f9bb114ea-v1/F_SteAvi.fst",
+        "http://mpassets.highfidelity.com/da2ad4cd-47d4-41da-b764-41f39ff77e30-v1/F_JerGir.fst",
+        "http://mpassets.highfidelity.com/96c747ab-f71b-44ee-8eb9-d19fc9593dda-v1/F_CatBur.fst",
+        "http://mpassets.highfidelity.com/ede82c38-c66e-4f67-9e0b-0bb0782db18f-v1/M_WesOut.fst",
+        "http://mpassets.highfidelity.com/8872ae86-a763-4db3-8373-d27514c1481e-v1/M_VinAvi.fst",
+        "http://mpassets.highfidelity.com/faf505f1-4fd1-4ed2-8909-816af246c48f-v1/M_VicGen.fst",
+        "http://mpassets.highfidelity.com/d807a7d2-5122-4436-a6f9-3173c94d1c49-v1/M_SuaGen.fst",
+        "http://mpassets.highfidelity.com/1dd41735-06f4-45a3-9ec0-d05215ace77b-v1/M_MarSen.fst",
+        "http://mpassets.highfidelity.com/2cad3894-8ab3-4ba5-a723-0234f93fbd6a-v1/M_BowBea.fst",
+        "http://mpassets.highfidelity.com/cf0eb1be-9ec7-4756-8eaf-ac8f3ec09eba-v1/F_ClaDef.fst",
+        "http://mpassets.highfidelity.com/0cedeca3-c1a4-4be9-9fd5-dad716afcc7e-v1/F_Cyria.fst",
+        "http://mpassets.highfidelity.com/dc55803b-9215-47dd-9408-eb835dac4082-v1/F_ParGir.fst",
+        "http://mpassets.highfidelity.com/775a8fb3-cfe7-494d-b603-a0a2d6910e55-v1/F_VinCov.fst",
+        "http://mpassets.highfidelity.com/eba0d8f8-aa72-4a6b-ab64-4d3fd4695b20-v1/F_VogHei.fst",
+        "http://mpassets.highfidelity.com/4f400c78-38f9-42af-b03b-11b5451d41b9-v1/M_MidRog.fst",
+        "http://mpassets.highfidelity.com/ad774d79-13f1-46e2-87c9-de49a261b264-v1/F_GunSli.fst",
+        "http://mpassets.highfidelity.com/5acbaefa-5455-49a2-8d40-89d12aa393ca-v1/M_KniWol.fst",
+        "http://mpassets.highfidelity.com/aaa1b0a8-3e1b-492a-9aee-600e5dc907db-v1/F_RetSciSuit.fst",
+        "http://mpassets.highfidelity.com/d8da10b6-25c1-40e2-9a66-369316c722d7-v1/F_AniSuit.fst",
+        "http://mpassets.highfidelity.com/f3fbb9f4-e159-49ed-ac32-03af9056b17e-v1/matthew.fst",
+        "http://mpassets.highfidelity.com/0c954ba0-4d87-4353-b65e-c45509f85658-v1/priscilla.fst",
+        "http://mpassets.highfidelity.com/e76946cc-c272-4adf-9bb6-02cde0a4b57d-v1/9e8c5c42a0cbd436962d6bd36f032ab3.fst",
+        "http://mpassets.highfidelity.com/72e083ee-194d-4113-9c61-0591d8257493-v1/skeleton_Rigged.fst",
+        "http://mpassets.highfidelity.com/f14bf7c9-49a1-4249-988a-0a577ed78957-v1/beingOfLight.fst",
+        "http://mpassets.highfidelity.com/1b7e1e7c-6c0b-4f20-9cd0-1d5ccedae620-v1/bb64e937acf86447f6829767e958073c.fst",
+        "http://mpassets.highfidelity.com/67d7c7aa-c300-4d03-85f4-86480130eaa5-v1/F_StarCrew.fst",
+        "http://mpassets.highfidelity.com/d293ef06-c659-467a-9288-c3cbaff0372a-v1/arya_avatar.fst",
+        "http://mpassets.highfidelity.com/faf249d5-12a8-48e2-a08e-fb0c33087011-v1/F_Ranger.fst",
+        "http://mpassets.highfidelity.com/b4502145-15eb-4023-b7d6-a81c5cbf6abf-v1/F_FitTra.fst",
+        "http://mpassets.highfidelity.com/548d0792-0bac-4933-bbfc-57d71912d77e-v1/M_OutMer.fst",
+        "http://mpassets.highfidelity.com/caa61e5d-5629-4165-81d8-6a7eb55e942d-v1/F_DeaSur.fst",
+        "http://mpassets.highfidelity.com/2cad3894-8ab3-4ba5-a723-0234f93fbd6a-v1/M_BowBea.fst",
+        "http://mpassets.highfidelity.com/fd4fa45a-9d2a-463e-a484-f9d1b3bba724-v1/M_BeaWar.fst",
+        "http://mpassets.highfidelity.com/367a5b60-8a92-4d56-a152-a00f3086f02b-v1/M_Espio.fst",
+        "http://mpassets.highfidelity.com/ab466729-31da-4b4c-a33c-366f7c1d38e5-v1/M_MMAFig.fst",
+        "http://mpassets.highfidelity.com/b0795a0c-493d-4abd-b4cc-5f32e6d6df46-v1/M_SalMer.fst",
+        "http://mpassets.highfidelity.com/0a1d44bf-a988-4199-b29e-a532ab85a2e8-v1/M_StaShi.fst",
+        "http://mpassets.highfidelity.com/d807a7d2-5122-4436-a6f9-3173c94d1c49-v1/M_SuaGen.fst",
+        "http://mpassets.highfidelity.com/cb20212c-36f2-4d41-bdad-132361ca6ff4-v1/M_TreTee.fst",
+        "http://mpassets.highfidelity.com/830988dc-619a-4e88-96e1-a19fa0aaa30f-v1/M_UrbEnf.fst",
+        "http://mpassets.highfidelity.com/faf505f1-4fd1-4ed2-8909-816af246c48f-v1/M_VicGen.fst",
+        "http://mpassets.highfidelity.com/883ac86f-dd29-4676-8bda-7dd52fb6465f-v1/M_WasWan.fst",
+        "http://mpassets.highfidelity.com/ede82c38-c66e-4f67-9e0b-0bb0782db18f-v1/M_WesOut.fst",
+        "http://mpassets.highfidelity.com/04c9a1e9-0390-4a7f-b6c6-5f135c19e3fb-v1/F_ArmTro.fst",
+        "http://mpassets.highfidelity.com/e863348f-a777-4f36-86e6-af6e65ffa161-v1/F_BloSam.fst",
+        "http://mpassets.highfidelity.com/cf0eb1be-9ec7-4756-8eaf-ac8f3ec09eba-v1/F_ClaDef.fst",
+        "http://mpassets.highfidelity.com/0cedeca3-c1a4-4be9-9fd5-dad716afcc7e-v1/F_Cyria.fst",
+        "http://mpassets.highfidelity.com/da2ad4cd-47d4-41da-b764-41f39ff77e30-v1/F_JerGir.fst",
+        "http://mpassets.highfidelity.com/534d42f8-ec13-4145-929f-5c8facac2fb7-v1/F_LegFig.fst",
+        "http://mpassets.highfidelity.com/dc55803b-9215-47dd-9408-eb835dac4082-v1/F_ParGir.fst",
+        "http://mpassets.highfidelity.com/f823e831-d8c4-4191-a3bd-427e406e69f9-v1/F_Shinjuku.fst",
+        "http://mpassets.highfidelity.com/eba0d8f8-aa72-4a6b-ab64-4d3fd4695b20-v1/F_VogHei.fst",
+        "http://mpassets.highfidelity.com/13277c09-892f-4a5e-b9a5-8994a37d68bf-v1/F_WasWar.fst",
+        "http://mpassets.highfidelity.com/9b589fbb-59e4-47a9-8b3f-bf8d3a0bd1d8-v1/M_LawSur.fst",
+        "http://mpassets.highfidelity.com/4f400c78-38f9-42af-b03b-11b5451d41b9-v1/M_MidRog.fst",
+        "http://mpassets.highfidelity.com/c90d755d-0456-48fd-b98c-09c4d85cd481-v1/M_MouOff.fst",
+        "http://mpassets.highfidelity.com/c2ed3b9a-b3a9-4424-9fd2-8a798209f32b-v1/M_PerTra.fst",
+        "http://mpassets.highfidelity.com/c48928ac-7657-41f4-bbdc-9b47385736ab-v1/M_SpaMar.fst",
+        "http://mpassets.highfidelity.com/d029ae8d-2905-4eb7-ba46-4bd1b8cb9d73-v1/4618d52e711fbb34df442b414da767bb.fst",
+        "http://mpassets.highfidelity.com/c85c497d-c87b-42b1-9bbf-5405e05a0ad3-v1/M_ArmSol.fst",
+        "http://mpassets.highfidelity.com/1dd41735-06f4-45a3-9ec0-d05215ace77b-v1/M_MarSen.fst",
+        "http://mpassets.highfidelity.com/bd80a6d7-7173-489e-87c6-f7ee56e65530-v1/M_RetFut.fst",
+        "http://mpassets.highfidelity.com/8872ae86-a763-4db3-8373-d27514c1481e-v1/M_VinAvi.fst",
+        "http://mpassets.highfidelity.com/f798d926-9a9e-481a-b298-af0e45451252-v1/F_Assassin.fst",
+        "http://mpassets.highfidelity.com/ad774d79-13f1-46e2-87c9-de49a261b264-v1/F_GunSli.fst",
+        "http://mpassets.highfidelity.com/aaa1b0a8-3e1b-492a-9aee-600e5dc907db-v1/F_RetSciSuit.fst"
+     ];
+
+
+var AVATAR_URL = AVATARS_ARRAY[Math.floor(Math.random() * AVATARS_ARRAY.length)];
+print("RANDOM AVATAR SELECTED:" + AVATAR_URL);
+
+var RECORDINGS_ARRAY = [
+        "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/waiting6.hfr",
+        "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/waiting7.hfr",
+        "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/waiting10.hfr",
+        "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/bot1.hfr",
+        "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/bot2.hfr",
+        "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/bot3.hfr",
+        "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/bot4.hfr"
+    ];
+
+var RECORDING_URL = RECORDINGS_ARRAY[Math.floor(Math.random() * RECORDINGS_ARRAY.length)];
+print("RANDOM RECORDING SELECTED:" + RECORDING_URL);
+
+// not quite what I want...
+var LOCATIONS_ARRAY = [
+  { min_x: -91, max_x: -40, y: -19.2, min_z: -1.8, max_z: 90   }
+];
+
+var LOCATION_PARAMS = LOCATIONS_ARRAY[Math.floor(Math.random() * LOCATIONS_ARRAY.length)];
+
+var LOCATION = { x: randFloat(LOCATION_PARAMS.min_x, LOCATION_PARAMS.max_x), y: LOCATION_PARAMS.y, z: randFloat(LOCATION_PARAMS.min_z, LOCATION_PARAMS.max_z) };
+
+Vec3.print("RANDOM LOCATION SELECTED:", LOCATION);
+
+var playFromCurrentLocation = true;
+var loop = true;
+
+// Disable the privacy bubble
+Users.disableIgnoreRadius();
+
+// Set position here if playFromCurrentLocation is true
+Avatar.position = LOCATION;
+Avatar.orientation = Quat.fromPitchYawRollDegrees(1, 0, 0);
+Avatar.scale = 1.0;
+Agent.isAvatar = true;
+
+// make the agent "listen" to the audio stream to cause additional audio-mixer load, technically this isn't needed when you're playing a recording
+// but if you switch to a non-recording bot, you will need this, so we can leave this.
+Agent.isListeningToAudioStream = true;
+Avatar.skeletonModelURL = AVATAR_URL; // FIXME - currently setting an avatar while playing a recording doesn't work it will be ignored
+
+
+function messageLog(channel, sender, message) {
+    if (channel === MESSAGE_CHANNEL) {
+        print ("AC Bot at position: " + JSON.stringify(Avatar.position) + " received message on " + MESSAGE_CHANNEL);
+    }
+}
+
+Recording.loadRecording(RECORDING_URL, function(success) {
+    if (success) {
+        Script.update.connect(update);
+        Messages.subscribe(MESSAGE_CHANNEL);
+        Messages.messageReceived.connect(messageLog);
+    } else {
+        print("Failed to load recording from " + RECORDING_URL);
+    }
+});
+
+
+count = 300; // This is necessary to wait for the audio mixer to connect
+function update(event) {
+    if (count > 0) {
+        count--;
+        return;
+    }
+    if (count == 0) {
+        Recording.setPlayFromCurrentLocation(playFromCurrentLocation);
+        Recording.setPlayerLoop(loop);
+        Recording.setPlayerUseDisplayName(true);
+        Recording.setPlayerUseAttachments(true);
+        Recording.setPlayerUseHeadModel(false);
+        Recording.setPlayerUseSkeletonModel(false); // FIXME - this would allow you to override the recording avatar, but that's not currently working
+        Recording.startPlaying();
+        Vec3.print("Playing from ", Avatar.position);
+        count--;
+    } else if (WANT_DEBUGGING) {
+        count = 100;
+        Vec3.print("Avatar at: ", Avatar.position);
+        Quat.print("Avatar head orientation: ", Avatar.headOrientation);
+        print("outbound:"
+            +" GP: " + Avatar.getDataRate("globalPositionOutbound").toFixed(2) + "\n"
+            +" LP: " + Avatar.getDataRate("localPositionOutbound").toFixed(2) + "\n"
+            +" BB: " + Avatar.getDataRate("avatarBoundingBoxOutbound").toFixed(2) + "\n"
+            +" AO: " + Avatar.getDataRate("avatarOrientationOutbound").toFixed(2) + "\n"
+            +" AS: " + Avatar.getDataRate("avatarScaleOutbound").toFixed(2) + "\n"
+            +" LA: " + Avatar.getDataRate("lookAtPositionOutbound").toFixed(2) + "\n"
+            +" AL: " + Avatar.getDataRate("audioLoudnessOutbound").toFixed(2) + "\n"
+            +" SW: " + Avatar.getDataRate("sensorToWorkMatrixOutbound").toFixed(2) + "\n"
+            +" AF: " + Avatar.getDataRate("additionalFlagsOutbound").toFixed(2) + "\n"
+            +" PI: " + Avatar.getDataRate("parentInfoOutbound").toFixed(2) + "\n"
+            +" FT: " + Avatar.getDataRate("faceTrackerOutbound").toFixed(2) + "\n"
+            +" JD: " + Avatar.getDataRate("jointDataOutbound").toFixed(2));
+    }
+
+    if (!Recording.isPlaying()) {
+        Script.update.disconnect(update);
+        Messages.unsubscribe(MESSAGE_CHANNEL);
+        Messages.messageReceived.disconnect(messageLog);
+    }
+}
+
+Script.scriptEnding.connect(function(){
+    Messages.unsubscribe(MESSAGE_CHANNEL);
+});
\ No newline at end of file
diff --git a/hifi-content/howell/Prototypes/best_game.jpg b/hifi-content/howell/Prototypes/best_game.jpg
new file mode 100644
index 000000000..21de3c1b5
--- /dev/null
+++ b/hifi-content/howell/Prototypes/best_game.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5db32657baee0bfc6ccae71cfb87f81a5f9b40037bcb9d237543406a3fc5b517
+size 95702
diff --git a/hifi-content/howell/Prototypes/bot_player_content_v4/assignmentClientManager_andy_test.js b/hifi-content/howell/Prototypes/bot_player_content_v4/assignmentClientManager_andy_test.js
new file mode 100644
index 000000000..ff04f194f
--- /dev/null
+++ b/hifi-content/howell/Prototypes/bot_player_content_v4/assignmentClientManager_andy_test.js
@@ -0,0 +1,247 @@
+"use strict";
+
+//
+//  Bot Player
+//  assignmentClientManager.js
+//  Created by Milad Nazeri on 2019-06-06
+//  Copyright 2019 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+
+(function() {
+
+    // *************************************
+    // START UTILITY FUNCTIONS
+    // *************************************
+    // #region UTILITY FUNCTIONS   
+    
+
+    // Start playing sequence to fill players with bots
+    var AC_AVAILABILITY_CHECK_MS = 1000;
+    function startSequence() {
+        // Check to see how many bots are needed
+        if (botCount >= botsFound + 1) {
+            return;
+        }
+
+        if (botCount < availableAssignmentClientPlayers.length) {
+            var player = availableAssignmentClientPlayers[botCount];
+            player.play();
+            botCount++;
+
+            if (botCount >= botsFound + 1) {
+                return;
+            }
+        }
+
+        Script.setTimeout(function() {
+            startSequence();
+        }, AC_AVAILABILITY_CHECK_MS);
+    }
+
+
+    // Searching through the s3 bucket to grab which recordings are valid and stop as soon as we get an error
+    // Synchronous version of require
+    var BASE_PATH = "https://hifi-content.s3.amazonaws.com/howell/bots_new/";
+    var MAX_BOTS_TO_TRY = 100;
+    var requestSync = Script.require("./requestSync.js").request;
+    var botsFound = 0;
+    function populateRecordingList(){
+        for (var i = 1; i < MAX_BOTS_TO_TRY; i++) {
+            var botRecordingFound = true;
+            var currentBotUrl = BASE_PATH + "AVATAR_TEST" + i + ".hfr";
+            requestSync(currentBotUrl, function(error){
+                if (error) {
+                    botRecordingFound = false;
+                } else {
+                    botsFound++;
+                    botList.push(currentBotUrl);
+                }
+            });
+            if (!botRecordingFound) {
+                break;
+            }
+        }
+    }
+
+
+    // #endregion
+    // *************************************
+    // END UTILITY FUNCTIONS
+    // *************************************
+
+    // *************************************
+    // START CONSTS_AND_VARS
+    // *************************************
+    // #region CONSTS_AND_VARS
+
+
+    // The Assignment Client channel
+    var ASSIGNMENT_MANAGER_CHANNEL = "ASSIGNMENT_MANAGER_CHANNEL";
+    var ASSIGNMENT_CLIENT_MESSANGER_CHANNEL = "ASSIGNMENT_CLIENT_MESSANGER_CHANNEL";
+
+    // Array of the assignment client players and their assignment client player object
+    var availableAssignmentClientPlayers = [];
+
+    // Current playing bot count we are at
+    var botCount = 0;
+
+    // Current registered bount count
+    var botsRegisteredCount = 0;
+
+    // Array of the recordings found
+    var botList = [];
+
+
+    // #endregion
+    // *************************************
+    // END CONSTS_AND_VARS
+    // *************************************
+
+    // *************************************
+    // START ASSIGNMENT_CLIENT_PLAYER
+    // *************************************
+    // #region ASSIGNMENT_CLIENT_PLAYER
+
+
+    // Individual AssignmentClientPlayerObject
+    function AssignmentClientPlayerObject(uuid, fileToPlay, position, volume) {
+        this.uuid = uuid;
+        this.fileToPlay = fileToPlay;
+    }
+
+
+    // Play the current clip
+    function play() {
+        Messages.sendMessage(ASSIGNMENT_MANAGER_CHANNEL, JSON.stringify({
+            action: "PLAY",
+            fileToPlay: this.fileToPlay,
+            uuid: this.uuid
+        }));
+    }
+
+
+    // Stop the current clip
+    function stop() {
+        Messages.sendMessage(ASSIGNMENT_MANAGER_CHANNEL, JSON.stringify({
+            action: "STOP",
+            uuid: this.uuid
+        }));
+    }
+
+
+    AssignmentClientPlayerObject.prototype = {
+        play: play,
+        stop: stop
+    };
+
+
+    // #endregion
+    // *************************************
+    // END ASSIGNMENT_CLIENT_PLAYER
+    // *************************************
+    
+    // *************************************
+    // START MESSAGES
+    // *************************************
+    // #region MESSAGES
+
+
+    // Handle Messages received
+    function onMangerChannelMessageReceived(channel, message, sender) {
+        if (channel !== ASSIGNMENT_MANAGER_CHANNEL || sender === Agent.sessionUUID) {
+            return;
+        }
+
+        try {
+            message = JSON.parse(message);
+        } catch (error) {
+            console.log("invalid object");
+            console.log("MESSAGE:", message);
+            return;
+        }
+
+        switch (message.action) {
+            case "REGISTER_ME":
+                var fileName = botList[botsRegisteredCount];
+                availableAssignmentClientPlayers.push( 
+                    new AssignmentClientPlayerObject(message.uuid, fileName));
+                botsRegisteredCount++;
+                var messageToSend = JSON.stringify({
+                    action: "AC_AVAILABLE_UPDATE",
+                    newAvailableACs: availableAssignmentClientPlayers.length
+                });
+                Messages.sendMessage(ASSIGNMENT_CLIENT_MESSANGER_CHANNEL, messageToSend);
+                break;
+            case "ARE_YOU_THERE_MANAGER_ITS_ME_BOT":
+                Messages.sendMessage(ASSIGNMENT_MANAGER_CHANNEL, JSON.stringify({
+                    action: "REGISTER_MANAGER",
+                    uuid: sender
+                }));
+                break;
+            default:
+                console.log("unrecognized action in assignmentClientManger.js");
+                break;
+        }
+    }
+
+
+    // #endregion
+    // *************************************
+    // END MESSAGES
+    // *************************************
+
+    // *************************************
+    // START MAIN
+    // *************************************
+    // #region MAIN
+    
+    
+    // Startup for the manager when it comes online
+    function startUp() {
+        Messages.subscribe(ASSIGNMENT_MANAGER_CHANNEL);
+        Messages.subscribe(ASSIGNMENT_CLIENT_MESSANGER_CHANNEL);
+        Messages.messageReceived.connect(onMangerChannelMessageReceived);
+        Script.scriptEnding.connect(onEnding);
+        populateRecordingList();
+        startSequence();
+    }    
+    
+    startUp();
+    
+
+    // #endregion
+    // *************************************
+    // END MAIN
+    // *************************************
+
+    // *************************************
+    // START CLEANUP
+    // *************************************
+    // #region CLEANUP
+
+    
+    // Cleanup the manager and it's messages
+    function onEnding() {
+        Messages.messageReceived.disconnect(onMangerChannelMessageReceived);
+        var messageToSend = JSON.stringify({
+            action: "GET_MANAGER_STATUS",
+            newAvailableACs: 0,
+            isPlaying: false,
+            closeTablet: true
+        });
+        Messages.sendMessage(ASSIGNMENT_CLIENT_MESSANGER_CHANNEL, messageToSend);
+        Messages.unsubscribe(ASSIGNMENT_MANAGER_CHANNEL);
+        Messages.unsubscribe(ASSIGNMENT_CLIENT_MESSANGER_CHANNEL);
+    }
+
+
+    // #endregion
+    // *************************************
+    // END CLEANUP
+    // *************************************
+
+})();
diff --git a/hifi-content/howell/Prototypes/bouncer.js b/hifi-content/howell/Prototypes/bouncer.js
new file mode 100644
index 000000000..ce54d5497
--- /dev/null
+++ b/hifi-content/howell/Prototypes/bouncer.js
@@ -0,0 +1,270 @@
+//
+//  ZoneScript.js
+//
+//  This script serves as a virtual bouncer depending on username or whether or not a client can validate
+//  ownership of a particular specified avatar entity. Can one or all three methods: hardcoded list in APPROVED_USERNAMES,
+//  inside entity userData username list, and/or verifying an wearable marketplace entity through it's ID. 
+//
+//  Copyright 2017 High Fidelity, Inc.
+//
+//  Set Up: 
+//     1. Add below userData object to zone entity userData
+//          1. Fill in rejectTeleportLocation, example "/13.9828,-10.5277,0.0609192/0,0.460983,0,0.887409"
+//          2. Optional: add marketplaceID of the item to verify
+//          3. Optional: (can update while script is running): each username to add to whitelist
+//     2. Add approved users to APPROVED_USERNAMES below, keep blank if not using
+//     3. Add script to zone entity
+//     4. Update userData at anytime to add more to usernames your whitelist
+// 
+// Add this to the zone userData : 
+// {
+//     "whitelist" : {
+//         "rejectTeleportLocation" : "<<INSERT HIFI ADDRESS>>"
+//         "marketplaceID" : "<<INSERT MARKETPLACE ITEM ID>>",
+//         "usernames" : [""]
+//     },
+//    "grabbableKey": {
+//       "grabbable": false
+//     }
+// }
+//
+// whitelist - (required) contains variables for the zone
+//     rejectTeleportLocation - (required) rejected avatars are sent to these domain coordinates
+//     marketplaceID - (optional) marketplace item id for marketplace item verification
+//     usernames - (optional) array for usernames to be added while script is running
+// 
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+
+/* globals Entities, Wallet, Window, AccountServices */
+
+(function () {
+
+    // username lookup variables
+    var APPROVED_USERNAMES = []; // hardcoded
+    var whitelist = []; // stores lowercase usernames from APPROVED_USERNAMES
+
+    // usernames inside userData
+    var _usernames; // userData names
+    
+    // marketplace lookup variables
+    var WEARABLE_SEARCH_RADIUS = 10;
+    var foundValidTestable = false;
+    var _foundEntityID = -1;
+    var _passMarketplaceID;
+    var _userDataProperties;
+    var _backupLocation;
+    
+    var _entityID;
+    var LOAD_TIME = 50;
+    var avatarCheckStep = 0;
+    var HALF = 0.5;
+    var DEBUG = false;
+
+    var marketplaceItem = {
+
+        verificationSuccess: function (entityID) {
+            if (DEBUG) {
+                print("You may enter - verification passed for entity: " + entityID);
+            }
+            Wallet.ownershipVerificationSuccess.disconnect(this.verificationSuccess);
+            Wallet.ownershipVerificationFailed.disconnect(this.verificationFailed);
+        },
+
+        verificationFailed: function (entityID) {
+            if (DEBUG) {
+                print("You may not enter - verification failed for entity: " + entityID);
+            }
+            utils.rejectTeleportAvatar();
+            Wallet.ownershipVerificationSuccess.disconnect(this.verificationSuccess);
+            Wallet.ownershipVerificationFailed.disconnect(this.verificationFailed);
+        },
+
+        verifyAvatarOwnership: function (entityID) {
+            Wallet.proveAvatarEntityOwnershipVerification(entityID);
+        },
+        searchForMatchingItem: function () {
+            Entities.findEntitiesByType('Model', MyAvatar.position, WEARABLE_SEARCH_RADIUS).forEach(function (entityID) {
+                var properties = Entities.getEntityProperties(entityID, ['marketplaceID', 'certificateID', 'parentID']);
+                if (properties.marketplaceID === _passMarketplaceID && properties.parentID === MyAvatar.sessionUUID) {
+                    _foundEntityID = entityID;
+                    foundValidTestable = true;
+                    this.verifyAvatarOwnership(_foundEntityID);
+                    Wallet.ownershipVerificationSuccess.connect(this.verificationSuccess);
+                    Wallet.ownershipVerificationFailed.connect(this.verificationFailed);
+                }
+            });
+            if (!foundValidTestable) {
+                utils.rejectTeleportAvatar();
+            }
+        }
+    };
+
+    var avatarUserName = {
+        isOnWhitelist: function () {
+            var username = AccountServices.username.toLowerCase();
+            if (whitelist.indexOf(username) >= 0) {
+                if (DEBUG) {
+                    print("Username is on hardcoded whitelist");
+                }
+                return true;
+            } else {
+                return false;
+            }
+        },
+        isInUserData: function () {
+            var username = AccountServices.username.toLowerCase();
+
+            for (var i = 0; i < _usernames.length; i++) {
+                if (_usernames[i].toLowerCase() === username) {
+                    if (DEBUG) {
+                        print("Username is on userData whitelist");
+                    }
+                    return true;
+                }
+            }
+            return false;
+        }
+    };
+
+    var utils = {
+
+        updateUserData: function () {
+            try {
+                _userDataProperties = JSON.parse(Entities.getEntityProperties(_entityID, 'userData').userData);
+            } catch (err) {
+                console.error("Error parsing userData: ", err);
+            }
+
+            _usernames = _userDataProperties.whitelist && _userDataProperties.whitelist.usernames || [];
+        },
+
+        rejectTeleportAvatar: function () {
+            if (DEBUG) {
+                print("Rejected from zone to: ", _backupLocation);
+            }
+            Window.location.handleLookupString(_backupLocation);
+        },
+
+        largestAxisVec: function (dimensions) {
+            var max = Math.max(dimensions.x, dimensions.y, dimensions.z);
+            return max;
+        },
+
+        isInEntity: function () {
+            var properties = Entities.getEntityProperties(_entityID, ["position", "dimensions", "rotation"]);
+            var position = properties.position;
+            var dimensions = properties.dimensions;
+            
+            var avatarPosition = MyAvatar.position;
+            var worldOffset = Vec3.subtract(avatarPosition, position);
+
+            avatarPosition = Vec3.multiplyQbyV(Quat.inverse(properties.rotation), worldOffset);
+
+            var minX = 0 - dimensions.x * HALF;
+            var maxX = 0 + dimensions.x * HALF;
+            var minY = 0 - dimensions.y * HALF;
+            var maxY = 0 + dimensions.y * HALF;
+            var minZ = 0 - dimensions.z * HALF;
+            var maxZ = 0 + dimensions.z * HALF;
+
+            if (avatarPosition.x >= minX && avatarPosition.x <= maxX
+                && avatarPosition.y >= minY && avatarPosition.y <= maxY
+                && avatarPosition.z >= minZ && avatarPosition.z <= maxZ) {
+                
+                if (DEBUG) {
+                    print("Avatar is inside zone");
+                }
+                return true;
+
+            } else {
+
+                if (DEBUG) {
+                    print("Avatar is NOT in zone");
+                }
+                return false;
+            }
+        }
+
+    };
+
+    var ProtectedZone = function () {
+
+    };
+
+    ProtectedZone.prototype = {
+
+        preload: function (entityID) {
+            _entityID = entityID;
+            var _this = this;
+
+            
+            if (APPROVED_USERNAMES.length > 0) {
+                APPROVED_USERNAMES.forEach(function (username) {
+                    whitelist.push(username.toLowerCase());
+                });
+            }
+            
+            utils.updateUserData();
+            
+            Script.setTimeout(function () {
+                if (_userDataProperties.whitelist) {
+    
+                    _passMarketplaceID = _userDataProperties.whitelist.marketplaceID || "";
+                    _backupLocation = _userDataProperties.whitelist.rejectTeleportLocation;
+                    _usernames = _userDataProperties.whitelist.usernames || [];
+    
+                }
+                _this.insideEntityCheck();
+
+            }, LOAD_TIME);
+
+        },
+        insideEntityCheck: function () {
+            // ensures every avatar experiences the enterEntity method
+            var properties = Entities.getEntityProperties(_entityID, ["position", "dimensions"]);
+            var largestDimension = utils.largestAxisVec(properties.dimensions);
+            var avatarsInRange = AvatarList.getAvatarsInRange(properties.position, largestDimension).filter(function(id) {
+                return id === MyAvatar.sessionUUID;
+            });
+    
+            if (avatarsInRange.length > 0) {
+                if (DEBUG) {
+                    print("Found avatar near zone: ", avatarCheckStep);
+                }
+                // do isInZone check
+                if (utils.isInEntity()) {
+                    this.enterEntity();
+                }
+            }
+        },
+        enterEntity: function () {
+            
+            utils.updateUserData();
+
+            Script.setTimeout(function () { 
+
+                var isInUserData = avatarUserName.isInUserData();
+                
+                if (isInUserData || (APPROVED_USERNAMES.length > 0 && avatarUserName.isOnWhitelist())) {
+                    // do nothing
+                } else {
+                    // did not pass username tests
+                    if (_passMarketplaceID) {
+                        // if marketplaceID exists look for item
+                        foundValidTestable = false;
+                        marketplaceItem.searchForMatchingItem(); // will reject within function
+                    } else {
+                        // otherwise reject avatar
+                        utils.rejectTeleportAvatar();
+                    }
+                }
+
+            }, LOAD_TIME);
+
+        }
+    };
+
+    return new ProtectedZone();
+
+});
\ No newline at end of file
diff --git a/hifi-content/howell/Prototypes/crabble.png b/hifi-content/howell/Prototypes/crabble.png
new file mode 100644
index 000000000..b41fe4da9
--- /dev/null
+++ b/hifi-content/howell/Prototypes/crabble.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:96d1d7254d45ddbaf8aa8dc1e07c2301a98295a74a6fb797c344b6fb69f82fb0
+size 9172
diff --git a/hifi-content/howell/Prototypes/dog_skull/dogskull.mtl b/hifi-content/howell/Prototypes/dog_skull/dogskull.mtl
new file mode 100644
index 000000000..e32b28f43
--- /dev/null
+++ b/hifi-content/howell/Prototypes/dog_skull/dogskull.mtl
@@ -0,0 +1,14 @@
+# 
+# Wavefront material file
+# Created in RealityCapture v1.0.3.4658
+# www.capturingreality.com
+# 
+
+
+newmtl dogskull_Material_u1_v1
+Ka 1 1 1
+Kd 1 1 1
+d 1
+Ns 0
+illum 1
+map_Kd dogskull_u1_v1.jpg
diff --git a/hifi-content/howell/Prototypes/dog_skull/dogskull.obj b/hifi-content/howell/Prototypes/dog_skull/dogskull.obj
new file mode 100644
index 000000000..aac6fb09b
--- /dev/null
+++ b/hifi-content/howell/Prototypes/dog_skull/dogskull.obj
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4e32bd05e62eb3e4b428f611364117ecffcfc60beec2e139155e226730f124e0
+size 5187505
diff --git a/hifi-content/howell/Prototypes/dog_skull/dogskull_u1_v1.jpg b/hifi-content/howell/Prototypes/dog_skull/dogskull_u1_v1.jpg
new file mode 100644
index 000000000..75674ebed
--- /dev/null
+++ b/hifi-content/howell/Prototypes/dog_skull/dogskull_u1_v1.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:be3619b68560da8c9ecb4680014ca2024c1a4815245b04a9cd9df939bba5f084
+size 566510
diff --git a/hifi-content/howell/Prototypes/glasses.jpg b/hifi-content/howell/Prototypes/glasses.jpg
new file mode 100644
index 000000000..26aa3eca1
--- /dev/null
+++ b/hifi-content/howell/Prototypes/glasses.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:893bbc9eb8ec5296bc168f28e9e73717fcbe5641c59fcbba3783411dad0dc7d8
+size 111129
diff --git a/hifi-content/howell/Prototypes/jat_test2/JATScritp.js b/hifi-content/howell/Prototypes/jat_test2/JATScritp.js
new file mode 120000
index 000000000..4a027c37a
--- /dev/null
+++ b/hifi-content/howell/Prototypes/jat_test2/JATScritp.js
@@ -0,0 +1 @@
+../JAT_test/JATScritp.js
\ No newline at end of file
diff --git a/hifi-content/howell/Prototypes/jat_test2/config.json b/hifi-content/howell/Prototypes/jat_test2/config.json
new file mode 120000
index 000000000..d476b91f5
--- /dev/null
+++ b/hifi-content/howell/Prototypes/jat_test2/config.json
@@ -0,0 +1 @@
+../JAT_test/config.json
\ No newline at end of file
diff --git a/hifi-content/howell/Prototypes/jat_test3/JATScritp.js b/hifi-content/howell/Prototypes/jat_test3/JATScritp.js
new file mode 120000
index 000000000..4a027c37a
--- /dev/null
+++ b/hifi-content/howell/Prototypes/jat_test3/JATScritp.js
@@ -0,0 +1 @@
+../JAT_test/JATScritp.js
\ No newline at end of file
diff --git a/hifi-content/howell/Prototypes/jat_test3/config.json b/hifi-content/howell/Prototypes/jat_test3/config.json
new file mode 100644
index 000000000..bab4ef25a
--- /dev/null
+++ b/hifi-content/howell/Prototypes/jat_test3/config.json
@@ -0,0 +1,27 @@
+{
+    "avatars": [
+        {
+            "name": "Andy1",
+            "url": "https://raw.githubusercontent.com/AndySeattle/Avatar/master/office_zombie_alive/office_zombie_alive.fst"
+        },
+        {
+            "name": "Vacation",
+            "url": "https://raw.githubusercontent.com/AndySeattle/Avatar/master/Zombie_on_vacation/zombie_on_vacation_hifi.fst"
+        },
+        {
+            "name": "Ice Hero",
+            "url": "http://mpassets.highfidelity.com/e238153a-21f4-4eba-8ab5-c6b10a0eb967-v1/avatar.fst"
+        },
+        {
+            "name": "Ice Hero2",
+            "url": "http://mpassets.highfidelity.com/e238153a-21f4-4eba-8ab5-c6b10a0eb967-v1/avatar.fst"
+        },
+        {
+            "name": "ice hero 3",
+            "url": "http://mpassets.highfidelity.com/e238153a-21f4-4eba-8ab5-c6b10a0eb967-v1/avatar.fst"
+        }
+    ],
+    "screenleapURL": "<URL to Screenleap associated with the Web Overlay that shows up in front of JAT>",
+    "controlsMessageChannel": "<Message channel used for presentation controls>",
+    "statusMessageChannel": "<Message channel used for changing presentation status text>"
+}
\ No newline at end of file
diff --git a/hifi-content/howell/Prototypes/neon_snowflake.jpg b/hifi-content/howell/Prototypes/neon_snowflake.jpg
new file mode 100644
index 000000000..79fa686f4
--- /dev/null
+++ b/hifi-content/howell/Prototypes/neon_snowflake.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3bfb883b0e50213df4c94a032ca6ec923a2a2db42f4044c64bee2391ed3bb846
+size 97273
diff --git a/hifi-content/howell/Prototypes/neonturkey.jpg b/hifi-content/howell/Prototypes/neonturkey.jpg
new file mode 100644
index 000000000..09050407d
--- /dev/null
+++ b/hifi-content/howell/Prototypes/neonturkey.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f20e6d01aa352b271d87abc354cbd7cef04586ae1cdf4a3a096e65e22ba24a86
+size 111176
diff --git a/hifi-content/howell/Prototypes/pants.JPG b/hifi-content/howell/Prototypes/pants.JPG
new file mode 100644
index 000000000..9153c3125
--- /dev/null
+++ b/hifi-content/howell/Prototypes/pants.JPG
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:276cb6ffb72c6c8056293a57805083d9b7f04db9f172cf59253f301c0307d9e6
+size 57787
diff --git a/hifi-content/howell/Prototypes/pumpkins.jpg b/hifi-content/howell/Prototypes/pumpkins.jpg
new file mode 100644
index 000000000..2e0032f75
--- /dev/null
+++ b/hifi-content/howell/Prototypes/pumpkins.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6096a4bd8321589982b32f7d4b88ac5dea8680930d3f339f1ab414f9f68ff9a9
+size 322425
diff --git a/hifi-content/howell/Prototypes/satdium.fbx b/hifi-content/howell/Prototypes/satdium.fbx
new file mode 100644
index 000000000..d0ab9de37
--- /dev/null
+++ b/hifi-content/howell/Prototypes/satdium.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:32b6e4ff38986bb5e00dc6308fc02df7f23e08a635929afd0798dd4ba70a2c4a
+size 3316816
diff --git a/hifi-content/howell/Prototypes/shirt.jpg b/hifi-content/howell/Prototypes/shirt.jpg
new file mode 100644
index 000000000..f08a2fe72
--- /dev/null
+++ b/hifi-content/howell/Prototypes/shirt.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:528968504004a0c1939076b50bfaf2fb20f825d9c1b98d5f7aa96d0365f3f451
+size 78865
diff --git a/hifi-content/howell/Prototypes/snowflake.PNG b/hifi-content/howell/Prototypes/snowflake.PNG
new file mode 100644
index 000000000..0d3fbb313
--- /dev/null
+++ b/hifi-content/howell/Prototypes/snowflake.PNG
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1f06cad98fe7c0456945ab0701f111fca696e21e359b3468b09413afec08913a
+size 348816
diff --git a/hifi-content/howell/Prototypes/space.jpg b/hifi-content/howell/Prototypes/space.jpg
new file mode 100644
index 000000000..f11c98346
--- /dev/null
+++ b/hifi-content/howell/Prototypes/space.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:68249cffab436921e5326a80e01e16b681689c8b8a44e350e89df9d5df27a174
+size 242924
diff --git a/hifi-content/howell/Prototypes/space2.jpg b/hifi-content/howell/Prototypes/space2.jpg
new file mode 100644
index 000000000..35b375e15
--- /dev/null
+++ b/hifi-content/howell/Prototypes/space2.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:915657c377ec8f664bcef5d0ed8344afecf7b86493a3a448d58f7201a73f0a20
+size 147379
diff --git a/hifi-content/howell/Prototypes/team_directory.PNG b/hifi-content/howell/Prototypes/team_directory.PNG
new file mode 100644
index 000000000..4d0c5b2bd
--- /dev/null
+++ b/hifi-content/howell/Prototypes/team_directory.PNG
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9dcea6bdd128e75bb99aae1717a5b552ce68113a06f27693d95b4349d4e16e89
+size 29101
diff --git a/hifi-content/howell/Prototypes/turkeybleh.png b/hifi-content/howell/Prototypes/turkeybleh.png
new file mode 100644
index 000000000..07622a8b9
--- /dev/null
+++ b/hifi-content/howell/Prototypes/turkeybleh.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ab45cb8a0edf4459ad856c581862b52e0e2a39d9d27cc7b87a14709743414ab6
+size 147349
diff --git a/hifi-content/howell/Prototypes/ugly_sweater.jpg b/hifi-content/howell/Prototypes/ugly_sweater.jpg
new file mode 100644
index 000000000..bdf549913
--- /dev/null
+++ b/hifi-content/howell/Prototypes/ugly_sweater.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b5a7337f0cad399bee35ebefa412d0f8acb8cda2d5b299c6f5af5edd5f8f94fc
+size 20781
diff --git a/hifi-content/howell/Prototypes/wheel_of_current_events.png b/hifi-content/howell/Prototypes/wheel_of_current_events.png
new file mode 100644
index 000000000..f812cab83
--- /dev/null
+++ b/hifi-content/howell/Prototypes/wheel_of_current_events.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:23e76865a807aed401b0cbb61516ac94474aa6ce1fdc8b63c4f412c08125de41
+size 90689
diff --git a/hifi-content/howell/bots/AVATAR_TEST1.hfr b/hifi-content/howell/bots/AVATAR_TEST1.hfr
new file mode 100644
index 000000000..f83d11201
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST1.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d1c912c52b81e0c826eebf36af923f53d712a96bb160521e477b1ab2a62937c1
+size 7974898
diff --git a/hifi-content/howell/bots/AVATAR_TEST10.hfr b/hifi-content/howell/bots/AVATAR_TEST10.hfr
new file mode 100644
index 000000000..73926b371
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST10.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:dc3513dcb18a9881d624589b2c9774d9bbf8624bd1cd8219628a77c4f3c1800a
+size 1135949
diff --git a/hifi-content/howell/bots/AVATAR_TEST11.hfr b/hifi-content/howell/bots/AVATAR_TEST11.hfr
new file mode 100644
index 000000000..bf5badf2d
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST11.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6bd91df2847a77d64f53f8eaadb83a1554e011686a4f632f81eadfa2f69991e8
+size 1591454
diff --git a/hifi-content/howell/bots/AVATAR_TEST12.hfr b/hifi-content/howell/bots/AVATAR_TEST12.hfr
new file mode 100644
index 000000000..62b8c6127
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST12.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fa2b7bdf58b049e0e33f308d72a73a142c42a12faf49121beda3c6c49fbf44f4
+size 1686480
diff --git a/hifi-content/howell/bots/AVATAR_TEST13.hfr b/hifi-content/howell/bots/AVATAR_TEST13.hfr
new file mode 100644
index 000000000..c51393d15
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST13.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:54cefee9dc45885ac676525e175ea723e1a838abb80c9fc32f828c59e1acf65d
+size 2204124
diff --git a/hifi-content/howell/bots/AVATAR_TEST14.hfr b/hifi-content/howell/bots/AVATAR_TEST14.hfr
new file mode 100644
index 000000000..6a91c1bd2
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST14.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f7faa106a9808d87784860dc7461c1d9c2fc27f612ef9cc57bdfc2b5c702c008
+size 1185194
diff --git a/hifi-content/howell/bots/AVATAR_TEST15.hfr b/hifi-content/howell/bots/AVATAR_TEST15.hfr
new file mode 100644
index 000000000..5b52952e3
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST15.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e450bd4b3ef294984738a769da71b694bfc55940e1071a33efc8fbf9d8a58d51
+size 2887841
diff --git a/hifi-content/howell/bots/AVATAR_TEST16.hfr b/hifi-content/howell/bots/AVATAR_TEST16.hfr
new file mode 100644
index 000000000..eb17e0191
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST16.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1f242f9423b60c5f347fa2fb6b89c125ee921fc8fc7be6254d371ef756da02ea
+size 1666494
diff --git a/hifi-content/howell/bots/AVATAR_TEST17.hfr b/hifi-content/howell/bots/AVATAR_TEST17.hfr
new file mode 100644
index 000000000..4fcdb31aa
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST17.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:08259f6135f2bac23632d50befd5a924c23b2791123ed23e051a7a9edc60ee58
+size 1426485
diff --git a/hifi-content/howell/bots/AVATAR_TEST18.hfr b/hifi-content/howell/bots/AVATAR_TEST18.hfr
new file mode 100644
index 000000000..658395473
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST18.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:98f3ff1147262a21ab6cd1a91e137ac75aef2f7ea84df1933fd6629a9558c8c1
+size 1363808
diff --git a/hifi-content/howell/bots/AVATAR_TEST19.hfr b/hifi-content/howell/bots/AVATAR_TEST19.hfr
new file mode 100644
index 000000000..7cc8ef467
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST19.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2bf086e1b8c0ab37cde6351a9fb7e0ca363e8d8a7a49ba6f0b45d20eb3b22e8a
+size 985808
diff --git a/hifi-content/howell/bots/AVATAR_TEST2.hfr b/hifi-content/howell/bots/AVATAR_TEST2.hfr
new file mode 100644
index 000000000..375651531
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST2.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0e3038a4e34576fe52aa9ceda70cb066fe93ddd46782d3db44827e3ecffe34d9
+size 2178570
diff --git a/hifi-content/howell/bots/AVATAR_TEST20.hfr b/hifi-content/howell/bots/AVATAR_TEST20.hfr
new file mode 100644
index 000000000..8611625cd
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST20.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:49675f51a8981e99aa5bc079819568a96bba348519f44cd22cc4d55b5bf55932
+size 1739628
diff --git a/hifi-content/howell/bots/AVATAR_TEST3.hfr b/hifi-content/howell/bots/AVATAR_TEST3.hfr
new file mode 100644
index 000000000..c405e31e4
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST3.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ee10abed9d2152c503739887a5af8b9a1bb827a6f2a931db839113072f1cce0f
+size 1667470
diff --git a/hifi-content/howell/bots/AVATAR_TEST4.hfr b/hifi-content/howell/bots/AVATAR_TEST4.hfr
new file mode 100644
index 000000000..5cd58f9c4
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST4.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4d2e20acb44e860edf402b2c8be36e3d510847b88276c9999a749ac6581f6e9a
+size 3584851
diff --git a/hifi-content/howell/bots/AVATAR_TEST5.hfr b/hifi-content/howell/bots/AVATAR_TEST5.hfr
new file mode 100644
index 000000000..d2902d69c
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST5.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9d88321eb90c0b276cd98a12b8e7b9f69ed4581588389ad2541cebd63ff4773a
+size 5587202
diff --git a/hifi-content/howell/bots/AVATAR_TEST6.hfr b/hifi-content/howell/bots/AVATAR_TEST6.hfr
new file mode 100644
index 000000000..138ea7ec9
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST6.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0783ee0db7bac33092c443fdcdd3702db8e36fc9a8a62836371534c11a8c79cb
+size 5949659
diff --git a/hifi-content/howell/bots/AVATAR_TEST7.hfr b/hifi-content/howell/bots/AVATAR_TEST7.hfr
new file mode 100644
index 000000000..2bceec911
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST7.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ce31d7e20ecba3ea824b7d0ca61e34a8e66e6b4cd415bfb76a658cf067f8984b
+size 2389461
diff --git a/hifi-content/howell/bots/AVATAR_TEST8.hfr b/hifi-content/howell/bots/AVATAR_TEST8.hfr
new file mode 100644
index 000000000..45f026812
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST8.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:46c2efb60681234de3eb8b50dddc2a3fb8b800bdf1e7902e5e1daae7e332f25c
+size 1879422
diff --git a/hifi-content/howell/bots/AVATAR_TEST9.hfr b/hifi-content/howell/bots/AVATAR_TEST9.hfr
new file mode 100644
index 000000000..3496db33f
--- /dev/null
+++ b/hifi-content/howell/bots/AVATAR_TEST9.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ab03e5e3ef6660decc90396b77b5ef337ec18ca44a4e73a448cbb107bfd03cee
+size 2547568
diff --git a/hifi-content/howell/bots/_AVATAR_TEST5.hfr b/hifi-content/howell/bots/_AVATAR_TEST5.hfr
new file mode 120000
index 000000000..3879f6d5f
--- /dev/null
+++ b/hifi-content/howell/bots/_AVATAR_TEST5.hfr
@@ -0,0 +1 @@
+AVATAR_TEST15.hfr
\ No newline at end of file
diff --git a/hifi-content/howell/bots_new/AVATAR_TEST1.hfr b/hifi-content/howell/bots_new/AVATAR_TEST1.hfr
new file mode 100644
index 000000000..6d13dd4f4
--- /dev/null
+++ b/hifi-content/howell/bots_new/AVATAR_TEST1.hfr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8144f99773cda75e348020f2acc1bef6180a7577f5e48649316e26b7b177a2e6
+size 2232992
diff --git a/hifi-content/howell/usertesting/can_you_see_me.txt b/hifi-content/howell/usertesting/can_you_see_me.txt
new file mode 100644
index 000000000..51ce371a0
--- /dev/null
+++ b/hifi-content/howell/usertesting/can_you_see_me.txt
@@ -0,0 +1 @@
+Shannon can you see this? 
\ No newline at end of file
diff --git a/hifi-content/huffman/avatars/tubeboy/tubeboy.fst b/hifi-content/huffman/avatars/tubeboy/tubeboy.fst
new file mode 100644
index 000000000..78d2321e0
--- /dev/null
+++ b/hifi-content/huffman/avatars/tubeboy/tubeboy.fst
@@ -0,0 +1,131 @@
+name = tubeboy
+type = body+head
+scale = 1
+filename = tubeboy/tubeboy.fbx
+texdir = tubeboy/textures
+joint = jointNeck = Neck
+joint = jointRoot = Hips
+joint = jointRightHand = RightHand
+joint = jointLeftHand = LeftHand
+joint = jointHead = HeadTop_End
+joint = jointLean = Spine
+freeJoint = LeftArm
+freeJoint = LeftForeArm
+freeJoint = RightArm
+freeJoint = RightForeArm
+bs = LipsLowerDown = LowerLipDown_Right = 0.69999999999999996
+bs = LipsLowerDown = LowerLipDown_Left = 0.69999999999999996
+bs = EyeOpen_L = EyesWide_Left = 1
+bs = LipsLowerOpen = LowerLipOut = 1
+bs = MouthDimple_L = Smile_Left = 0.25
+bs = BrowsU_L = BrowsUp_Left = 1
+bs = ChinLowerRaise = Jaw_Up = 1
+bs = MouthRight = Midmouth_Right = 1
+bs = JawLeft = JawRotateY_Left = 0.5
+bs = EyeOpen_R = EyesWide_Right = 1
+bs = LipsPucker = MouthNarrow_Right = 1
+bs = LipsPucker = MouthNarrow_Left = 1
+bs = EyeBlink_L = Blink_Left = 1
+bs = EyeBlink_R = Blink_Right = 1
+bs = JawOpen = MouthOpen = 0.69999999999999996
+bs = EyeSquint_L = Squint_Left = 1
+bs = BrowsU_C = BrowsUp_Right = 1
+bs = BrowsU_C = BrowsUp_Left = 1
+bs = MouthSmile_L = Smile_Left = 1
+bs = JawRight = Jaw_Right = 1
+bs = MouthFrown_R = Frown_Right = 1
+bs = Puff = CheekPuff_Right = 1
+bs = Puff = CheekPuff_Left = 1
+bs = BrowsD_R = BrowsDown_Right = 1
+bs = EyeSquint_R = Squint_Right = 1
+bs = MouthFrown_L = Frown_Left = 1
+bs = Sneer = Squint_Right = 0.5
+bs = Sneer = Squint_Left = 0.5
+bs = Sneer = NoseScrunch_Right = 0.75
+bs = Sneer = NoseScrunch_Left = 0.75
+bs = LipsUpperOpen = UpperLipOut = 1
+bs = JawFwd = JawForeward = 1
+bs = MouthLeft = Midmouth_Left = 1
+bs = MouthSmile_R = Smile_Right = 1
+bs = LipsUpperUp = UpperLipUp_Right = 0.69999999999999996
+bs = LipsUpperUp = UpperLipUp_Left = 0.69999999999999996
+bs = LipsUpperClose = UpperLipIn = 1
+bs = MouthDimple_R = Smile_Right = 0.25
+bs = LipsLowerClose = LowerLipIn = 1
+bs = LipsFunnel = TongueUp = 1
+bs = LipsFunnel = MouthWhistle_NarrowAdjust_Right = 0.5
+bs = LipsFunnel = MouthWhistle_NarrowAdjust_Left = 0.5
+bs = LipsFunnel = MouthNarrow_Right = 1
+bs = LipsFunnel = MouthNarrow_Left = 1
+bs = LipsFunnel = Jaw_Down = 0.35999999999999999
+bs = LipsFunnel = JawForeward = 0.39000000000000001
+bs = BrowsU_R = BrowsUp_Right = 1
+bs = ChinUpperRaise = UpperLipUp_Right = 0.5
+bs = ChinUpperRaise = UpperLipUp_Left = 0.5
+bs = BrowsD_L = BrowsDown_Left = 1
+jointIndex = RightArm = 16
+jointIndex = RightHandThumb1 = 35
+jointIndex = LeftUpLeg = 7
+jointIndex = Spine1 = 13
+jointIndex = LeftHandThumb2 = 60
+jointIndex = LeftToe_End = 11
+jointIndex = LeftHandPinky1 = 43
+jointIndex = LeftHandThumb4 = 62
+jointIndex = RightHandPinky1 = 19
+jointIndex = LeftLeg = 8
+jointIndex = RightHandThumb3 = 37
+jointIndex = RightHandMiddle4 = 30
+jointIndex = LeftHandPinky3 = 45
+jointIndex = RightHandMiddle1 = 27
+jointIndex = RightHandIndex3 = 33
+jointIndex = LeftHandIndex1 = 55
+jointIndex = LeftToeBase = 10
+jointIndex = LeftHandPinky4 = 46
+jointIndex = LeftHandRing4 = 50
+jointIndex = Head = 64
+jointIndex = LeftShoulder = 39
+jointIndex = RightHandRing3 = 25
+jointIndex = RightFoot = 4
+jointIndex = RightHandRing1 = 23
+jointIndex = RightHandThumb4 = 38
+jointIndex = RightHandRing4 = 26
+jointIndex = RightHandThumb2 = 36
+jointIndex = LeftHandPinky2 = 44
+jointIndex = Hips = 0
+jointIndex = RightHand = 18
+jointIndex = RightHandMiddle2 = 28
+jointIndex = LeftHandRing1 = 47
+jointIndex = RightToeBase = 5
+jointIndex = LeftHandMiddle4 = 54
+jointIndex = RightHandRing2 = 24
+jointIndex = Spine = 12
+jointIndex = HeadTop_End = 65
+jointIndex = LeftHandRing3 = 49
+jointIndex = Spine2 = 14
+jointIndex = LeftHandMiddle2 = 52
+jointIndex = LeftHandIndex3 = 57
+jointIndex = RightHandPinky4 = 22
+jointIndex = RightLeg = 3
+jointIndex = RightToe_End = 6
+jointIndex = LeftHandRing2 = 48
+jointIndex = LeftHandIndex2 = 56
+jointIndex = LeftHandThumb3 = 61
+jointIndex = RightHandIndex4 = 34
+jointIndex = LeftFoot = 9
+jointIndex = LeftForeArm = 41
+jointIndex = LeftHandMiddle3 = 53
+jointIndex = RightHandMiddle3 = 29
+jointIndex = Neck = 63
+jointIndex = RightForeArm = 17
+jointIndex = Layer_7 = 1
+jointIndex = LeftHandMiddle1 = 51
+jointIndex = RightUpLeg = 2
+jointIndex = RightHandPinky2 = 20
+jointIndex = LeftHand = 42
+jointIndex = RightHandIndex2 = 32
+jointIndex = LeftHandIndex4 = 58
+jointIndex = LeftArm = 40
+jointIndex = RightHandIndex1 = 31
+jointIndex = LeftHandThumb1 = 59
+jointIndex = RightHandPinky3 = 21
+jointIndex = RightShoulder = 15
diff --git a/hifi-content/huffman/avatars/tubeboy/tubeboy/tubeboy.fbx b/hifi-content/huffman/avatars/tubeboy/tubeboy/tubeboy.fbx
new file mode 100644
index 000000000..c2bb6a750
--- /dev/null
+++ b/hifi-content/huffman/avatars/tubeboy/tubeboy/tubeboy.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d0fcf3223cc5affce57dfe1235611659812fa6a85b8d84449c1630cf8546a9b5
+size 4457056
diff --git a/hifi-content/huffman/ctf/Portal-Red-Blue.svo.json b/hifi-content/huffman/ctf/Portal-Red-Blue.svo.json
new file mode 100644
index 000000000..50f0d3fed
--- /dev/null
+++ b/hifi-content/huffman/ctf/Portal-Red-Blue.svo.json
@@ -0,0 +1,175 @@
+{
+    "Entities": [
+        {
+            "clientOnly": 0,
+            "collisionsWillMove": 1,
+            "compoundShapeURL": "http://hifi-production.s3.amazonaws.com/tutorials/pingPongGun/Pingpong-Gun-New.obj",
+            "created": "2017-02-27T19:00:27Z",
+            "dimensions": {
+                "x": 0.17742760479450226,
+                "y": 0.38749998807907104,
+                "z": 0.99309998750686646
+            },
+            "dynamic": 1,
+            "gravity": {
+                "x": 0,
+                "y": -5,
+                "z": 0
+            },
+            "id": "{891a0f4b-b8b2-4825-ace1-f566e8718782}",
+            "lastEdited": 1488229103067753,
+            "lastEditedBy": "{0f6b0911-7faf-45af-bfd0-9726a9ef0a2e}",
+            "modelURL": "http://hifi-content.s3.amazonaws.com/alan/dev/Pingportal-Gun-New.fbx?1",
+            "name": "Tutorial Ping Pong Gun",
+            "owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
+            "position": {
+                "x": 1.4289360046386719,
+                "y": 0,
+                "z": 1.4532890319824219
+            },
+            "queryAACube": {
+                "scale": 1.0806869268417358,
+                "x": 0.88859254121780396,
+                "y": -0.54034346342086792,
+                "z": 0.91294556856155396
+            },
+            "rotation": {
+                "w": 0.51259636878967285,
+                "x": -0.5248645544052124,
+                "y": 0.5236133337020874,
+                "z": -0.43306630849838257
+            },
+            "script": "http://hifi-content.s3.amazonaws.com/alan/dev/Scripts/ping-portal-lionsgate-blue.js?4",
+            "shapeType": "compound",
+            "type": "Model",
+            "userData": "{\"grabbableKey\":{\"invertSolidWhileHeld\":true},\"wearable\":{\"joints\":{\"RightHand\":[{\"x\":0.1177130937576294,\"y\":0.12922893464565277,\"z\":0.08307232707738876},{\"x\":0.4934672713279724,\"y\":0.3605862259864807,\"z\":0.6394805908203125,\"w\":-0.4664038419723511}],\"LeftHand\":[{\"x\":0.09151676297187805,\"y\":0.13639454543590546,\"z\":0.09354984760284424},{\"x\":-0.19628101587295532,\"y\":0.6418180465698242,\"z\":0.2830369472503662,\"w\":0.6851521730422974}]}}}"
+        },
+        {
+            "clientOnly": 0,
+            "color": {
+                "blue": 255,
+                "green": 166,
+                "red": 41
+            },
+            "created": "2017-02-27T19:00:27Z",
+            "cutoff": 90,
+            "dimensions": {
+                "x": 5.0777130126953125,
+                "y": 5.0777130126953125,
+                "z": 5.0777130126953125
+            },
+            "falloffRadius": 2.2000000476837158,
+            "id": "{51782e1b-983b-477d-9a6d-5ab550c198df}",
+            "intensity": 5,
+            "lastEdited": 1488229094210296,
+            "lastEditedBy": "{0f6b0911-7faf-45af-bfd0-9726a9ef0a2e}",
+            "name": "PingPortal-Light",
+            "owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
+            "parentID": "{891a0f4b-b8b2-4825-ace1-f566e8718782}",
+            "position": {
+                "x": -0.071898072957992554,
+                "y": 0.1922331303358078,
+                "z": 0.59060537815093994
+            },
+            "queryAACube": {
+                "scale": 26.384571075439453,
+                "x": -21.061281204223633,
+                "y": -13.358207702636719,
+                "z": -58.344821929931641
+            },
+            "rotation": {
+                "w": -0.14616614580154419,
+                "x": 0.68834972381591797,
+                "y": -0.69469749927520752,
+                "z": -0.14915692806243896
+            },
+            "type": "Light"
+        },
+        {
+            "clientOnly": 0,
+            "collisionsWillMove": 1,
+            "compoundShapeURL": "http://hifi-production.s3.amazonaws.com/tutorials/pingPongGun/Pingpong-Gun-New.obj",
+            "created": "2017-02-27T20:45:19Z",
+            "dimensions": {
+                "x": 0.17742760479450226,
+                "y": 0.38749998807907104,
+                "z": 0.99309998750686646
+            },
+            "dynamic": 1,
+            "gravity": {
+                "x": 0,
+                "y": -5,
+                "z": 0
+            },
+            "id": "{25c38044-7ede-485c-815b-dddbf6496bcb}",
+            "lastEdited": 1488229023393654,
+            "lastEditedBy": "{0f6b0911-7faf-45af-bfd0-9726a9ef0a2e}",
+            "modelURL": "http://hifi-content.s3.amazonaws.com/alan/dev/PingPortal-Gun-red.fbx",
+            "name": "Portal-Gun",
+            "owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
+            "position": {
+                "x": 0,
+                "y": 0.0038486719131469727,
+                "z": 0
+            },
+            "queryAACube": {
+                "scale": 92.106178283691406,
+                "x": -54.764865875244141,
+                "y": -2.7994985580444336,
+                "z": -53.593635559082031
+            },
+            "rotation": {
+                "w": 0.64834010601043701,
+                "x": -0.34717363119125366,
+                "y": 0.36466187238693237,
+                "z": -0.57109308242797852
+            },
+            "script": "http://hifi-content.s3.amazonaws.com/alan/dev/Scripts/ping-portal-lionsgate-red.js",
+            "shapeType": "compound",
+            "type": "Model",
+            "userData": "{\"grabbableKey\":{\"invertSolidWhileHeld\":true},\"wearable\":{\"joints\":{\"RightHand\":[{\"x\":0.1177130937576294,\"y\":0.12922893464565277,\"z\":0.08307232707738876},{\"x\":0.4934672713279724,\"y\":0.3605862259864807,\"z\":0.6394805908203125,\"w\":-0.4664038419723511}],\"LeftHand\":[{\"x\":0.09151676297187805,\"y\":0.13639454543590546,\"z\":0.09354984760284424},{\"x\":-0.19628101587295532,\"y\":0.6418180465698242,\"z\":0.2830369472503662,\"w\":0.6851521730422974}]}}}"
+        },
+        {
+            "clientOnly": 0,
+            "color": {
+                "blue": 96,
+                "green": 23,
+                "red": 255
+            },
+            "created": "2017-02-27T20:45:19Z",
+            "cutoff": 90,
+            "dimensions": {
+                "x": 5.0777130126953125,
+                "y": 5.0777130126953125,
+                "z": 5.0777130126953125
+            },
+            "falloffRadius": 3.2000000476837158,
+            "id": "{e33b0529-361c-4515-b17c-534e4d1af5aa}",
+            "intensity": 5.4000000953674316,
+            "lastEdited": 1488229000832557,
+            "lastEditedBy": "{0f6b0911-7faf-45af-bfd0-9726a9ef0a2e}",
+            "name": "PingPortal-Light",
+            "owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
+            "parentID": "{25c38044-7ede-485c-815b-dddbf6496bcb}",
+            "position": {
+                "x": -0.071893095970153809,
+                "y": 0.1922280490398407,
+                "z": 0.5906517505645752
+            },
+            "queryAACube": {
+                "scale": 26.384571075439453,
+                "x": -18.223112106323242,
+                "y": -13.085569381713867,
+                "z": -64.876693725585938
+            },
+            "rotation": {
+                "w": -0.14616614580154419,
+                "x": 0.68831920623779297,
+                "y": -0.69469749927520752,
+                "z": -0.14915692806243896
+            },
+            "type": "Light"
+        }
+    ],
+    "Version": 66
+}
diff --git a/hifi-content/huffman/ctf/README.md b/hifi-content/huffman/ctf/README.md
new file mode 100644
index 000000000..78fd985d4
--- /dev/null
+++ b/hifi-content/huffman/ctf/README.md
@@ -0,0 +1,24 @@
+### ballClientEntity.js
+
+  * Keeps track of whether it is being held locally.
+  * Has a message interface to release the ball. This message is sent when the
+      portal gun bullet/orb hits the user.
+  * Releases the ball when the goal is touched, and sends a message to the goal
+
+### goalClientEntity.js
+
+ * Shoots fireworks when the ball is scored
+ * Manages a cooldown so the goal can only be triggered every 2 seconds (on the client, so technically if 2 clients
+   scored in a shorted period of time it would still trigger twice).
+
+### portalGunClientEntity.js
+
+Portal gun client entity script
+
+### portalBulletClientEntity.js
+
+Portal bullet client entity script. Teleports a user to the starting area when it hits a user
+
+### gunSpawnerClientEntity.js
+
+Spawns guns when it is clicked/grabbed/fargrabbed
diff --git a/hifi-content/huffman/ctf/ballClientEntity.js b/hifi-content/huffman/ctf/ballClientEntity.js
new file mode 100644
index 000000000..4a618ca2d
--- /dev/null
+++ b/hifi-content/huffman/ctf/ballClientEntity.js
@@ -0,0 +1,67 @@
+(function() {
+    var self = this;
+
+    var leftHeld = false;
+    var rightHeld = false;
+
+    self.preload = function(entityID) {
+        self.entityID = entityID;
+        Script.addEventHandler(entityID, "collisionWithEntity", self.onCollide);
+        print('preload');
+    };
+
+    self.startDistanceGrab = function(entityID, args) {
+        if (args[0] === 'left') {
+            leftHeld = true;
+        } else {
+            rightHeld = true;
+        }
+        print("startDistance", leftHeld, rightHeld);
+    };
+    self.startNearGrab = function(entityID, args) {
+        if (args[0] === 'left') {
+            leftHeld = true;
+        } else {
+            rightHeld = true;
+        }
+        print("startNear", leftHeld, rightHeld);
+    };
+    self.releaseGrab = function(entityID, args) {
+        if (args[0] === 'left') {
+            leftHeld = false;
+        } else {
+            rightHeld = false;
+        }
+        print("release", leftHeld, rightHeld);
+    };
+
+    self.onCollide = function(entityA, entityB, collision) {
+        var colliderName = Entities.getEntityProperties(entityB, 'name').name;
+        print("Collide", colliderName);
+        if (colliderName === "Portal/Goal") {
+            self.releaseBall();
+            Entities.callEntityMethod(entityB, 'onScored');
+        }
+    };
+
+    self.releaseBall = function() {
+        if (leftHeld || rightHeld) {
+            var hand;
+            if (leftHeld && rightHeld) {
+                hand = 'both';
+            } else if (!leftHeld && rightHeld) {
+                hand = 'right';
+            } else if (leftHeld && !rightHeld) {
+                hand = 'left';
+            }
+            Messages.sendMessage("Hifi-Hand-Drop", hand);
+        }
+    };
+
+    Messages.subscribe("Portal-Game");
+    Messages.messageReceived.connect(function(channel, message, sender) {
+        if (channel === "Portal-Game") {
+            self.releaseBall();
+        }
+    });
+});
diff --git a/hifi-content/huffman/ctf/firework.js b/hifi-content/huffman/ctf/firework.js
new file mode 100644
index 000000000..c723b34ed
--- /dev/null
+++ b/hifi-content/huffman/ctf/firework.js
@@ -0,0 +1,147 @@
+//
+//  firework.js
+//  examples/baseball/
+//
+//  Created by Ryan Huffman on Nov 9, 2015
+//  Copyright 2015 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+/* globals randomVec3, randomInt, randomColor, getSounds, playFireworkShow:true */
+
+Script.include("utils.js");
+
+var emitters = [];
+
+var smokeTrailSettings = {
+    "name":"ParticlesTest Emitter",
+    "type": "ParticleEffect",
+    "color":{"red":205,"green":84.41176470588235,"blue":84.41176470588235},
+    "maxParticles":1000,
+    "velocity": { x: 0, y: 18.0, z: 0 },
+    "lifetime": 20,
+    "lifespan":3,
+    "emitRate":100,
+    "emitSpeed":0.5,
+    "speedSpread":0,
+    "emitOrientation":{"x":0,"y":0,"z":0,"w":1},
+    "emitDimensions":{"x":0,"y":0,"z":0},
+    "emitRadiusStart":0.5,
+    "polarStart":1,
+    "polarFinish":1,
+    "azimuthStart":0,
+    "azimuthFinish":0,
+    "emitterShouldTrail": true,
+    "emitAcceleration":{"x":0,"y":-0.70000001192092896,"z":0},
+    "accelerationSpread":{"x":0,"y":0,"z":0},
+    "particleRadius":0.03999999910593033,
+    "radiusSpread":0,
+    "radiusStart":0.13999999910593033,
+    "radiusFinish":0.14,
+    "colorSpread":{"red":0,"green":0,"blue":0},
+    "colorStart":{"red":255,"green":255,"blue":255},
+    "colorFinish":{"red":255,"green":255,"blue":255},
+    "alpha":1,
+    "alphaSpread":0,
+    "alphaStart":1,
+    "alphaFinish":0,
+    "textures":"https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"
+};
+
+var fireworkSettings = {
+    "name":"ParticlesTest Emitter",
+    "type": "ParticleEffect",
+    "color":{"red":205,"green":84.41176470588235,"blue":84.41176470588235},
+    "maxParticles":1000,
+    "lifetime": 20,
+    "lifespan":15,
+    "emitRate":2000,
+    "emitSpeed":2.5,
+    "speedSpread":1.0,
+    "emitOrientation":{"x":-0.2,"y":0,"z":0,"w":0.7000000000000001},
+    "emitDimensions":{"x":0,"y":0,"z":0},
+    "emitRadiusStart":0.5,
+    "polarStart":0,
+    "polarFinish":Math.PI,
+    "azimuthStart":-Math.PI,
+    "azimuthFinish":Math.PI,
+    "emitAcceleration":{"x":0,"y":-1.70000001192092896,"z":0},
+    "accelerationSpread":{"x":0,"y":0,"z":0},
+    "particleRadius":0.02999999910593033,
+    "radiusSpread":0,
+    "radiusStart":0.13999999910593033,
+    "radiusFinish":0.14,
+    "colorSpread":{"red":0,"green":0,"blue":0},
+    "colorStart":{"red":255,"green":255,"blue":255},
+    "colorFinish":{"red":255,"green":255,"blue":255},
+    "alpha":1,
+    "alphaSpread":0,
+    "alphaStart":1,
+    "alphaFinish":0,
+    "textures":"http://hifi-content.s3.amazonaws.com/alan/dev/Particles/Particle-Spark.png"
+};
+
+var popSounds = getSounds([
+    "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/pop1.wav",
+    "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/pop2.wav",
+    "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/pop3.wav",
+    "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/pop4.wav"
+]);
+
+var launchSounds = getSounds([
+    "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/fire1.wav",
+    "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/fire2.wav",
+    "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/fire3.wav",
+    "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/fire4.wav"
+]);
+
+function playRandomSound(sounds, options) {
+    Audio.playSound(sounds[randomInt(sounds.length)], options);
+}
+
+function shootFirework(position, color, options) {
+    smokeTrailSettings.position = position;
+    smokeTrailSettings.velocity = randomVec3(-5, 5, 10, 20, -5, 5);
+    smokeTrailSettings.gravity = randomVec3(-5, 5, -9.8, -9.8, -5, 5);
+
+    playRandomSound(launchSounds, { position: position, volume: 3.0 });
+    var smokeID = Entities.addEntity(smokeTrailSettings);
+
+    Script.setTimeout(function() {
+        Entities.editEntity(smokeID, { emitRate: 0 });
+        var position = Entities.getEntityProperties(smokeID, ['position']).position;
+        fireworkSettings.position = position;
+        fireworkSettings.colorStart = color;
+        fireworkSettings.colorFinish = color;
+        var burstID = Entities.addEntity(fireworkSettings);
+        playRandomSound(popSounds, { position: position, volume: 3.0 });
+        Script.setTimeout(function() {
+            Entities.editEntity(burstID, { emitRate: 0 });
+        }, 250);
+        Script.setTimeout(function() {
+            Entities.deleteEntity(smokeID);
+            Entities.deleteEntity(burstID);
+        }, 10000);
+    }, 2000);
+}
+
+playFireworkShow = function(position, numberOfFireworks, duration, offsetRange, colorBegin, colorEnd) {
+    for (var i = 0; i < numberOfFireworks; i++) {
+        var randomOffset = randomVec3(-offsetRange.x/2, offsetRange.x/2,
+                                      -offsetRange.y/2, offsetRange.y/2,
+                                      -offsetRange.z/2, offsetRange.z/2);
+        var randomPosition = Vec3.sum(position, randomOffset);
+        Script.setTimeout(function(position) {
+            return function() {
+                var color = randomColor(colorBegin.red, colorEnd.red, 
+                                        colorBegin.green, colorEnd.green, 
+                                        colorBegin.blue, colorEnd.blue);
+                shootFirework(position, color, fireworkSettings);
+            };
+        }(randomPosition), Math.random() * duration);
+    }
+};
+//var position = Vec3.sum(MyAvatar.position, { x: 30, y: 0, z: 0 });
+//playFireworkShow(position, 10, 2000, { x: 0, y: 0, z: 0 }, { red: 0, green: 0, blue: 200 }, { red: 0, green: 0, blue: 200 });
diff --git a/hifi-content/huffman/ctf/goalClientEntity.js b/hifi-content/huffman/ctf/goalClientEntity.js
new file mode 100644
index 000000000..b16e63594
--- /dev/null
+++ b/hifi-content/huffman/ctf/goalClientEntity.js
@@ -0,0 +1,50 @@
+/* globals playFireworkShow */
+
+(function() {
+    Script.include("firework.js?" + Date.now());
+
+    var self = this;
+    var teleportSound = SoundCache.getSound(Script.resolvePath("sounds/teleport.raw"));
+    var inCooldown = false;
+
+    self.preload = function(entityID) {
+        self.entityID = entityID;
+
+        var userData = Entities.getEntityProperties(entityID, 'userData').userData;
+        try {
+            userData = JSON.parse(userData);
+            if (userData.beginColor !== undefined && userData.endColor !== undefined) {
+                self.beginColor = userData.beginColor;
+                self.endColor = userData.endColor;
+                print("bgin:", self.beginColor.red, self.beginColor.green, self.beginColor.blue);
+            } else {
+                print("ERROR, colors not found");
+            }
+        } catch (e) {
+            print("ERROR, could not find gun color");
+        }
+    };
+
+    self.onScored = function() {
+        if (inCooldown) {
+            return;
+        }
+
+        var position = Entities.getEntityProperties(self.entityID, 'position').position;
+        playFireworkShow(position, 20, 3000,
+                { x: 5, y: 2, z: 5 },
+                self.beginColor,
+                self.endColor);
+        Audio.playSound(teleportSound, {
+            position: position,
+            volume: 0.40
+        });
+        inCooldown = true;
+        Script.setTimeout(function() {
+            inCooldown = false;
+        }, 2000);
+    };
+});
+
+
+// http://hifi-content.s3.amazonaws.com/caitlyn/production/soundEmitter/soundLoopEmitter.js
diff --git a/hifi-content/huffman/ctf/gunSpawnerClientEntity.js b/hifi-content/huffman/ctf/gunSpawnerClientEntity.js
new file mode 100644
index 000000000..8121cfc7a
--- /dev/null
+++ b/hifi-content/huffman/ctf/gunSpawnerClientEntity.js
@@ -0,0 +1,124 @@
+(function() {
+    var GUN_RED_MODEL_URL = Script.resolvePath("models/portalgun_red.fbx");
+    var GUN_BLUE_MODEL_URL = Script.resolvePath("models/portalgun_blue.fbx");
+
+    var gunProps = {
+        "collisionsWillMove": 1,
+        "compoundShapeURL": Script.resolvePath("models/portalgun_collider.obj"),
+        "dimensions": {
+            "x": 0.17742760479450226,
+            "y": 0.38749998807907104,
+            "z": 0.99309998750686646
+        },
+        "dynamic": 1,
+        "gravity": {
+            "x": 0,
+            "y": -5,
+            "z": 0
+        },
+        "modelURL": Script.resolvePath("models/portalgun_red.fbx"),
+        "name": "Portal/Gun",
+        "position": {
+            "x": 1.4289360046386719,
+            "y": 0,
+            "z": 1.4532890319824219
+        },
+        "rotation": {
+            "w": 0.51259636878967285,
+            "x": -0.5248645544052124,
+            "y": 0.5236133337020874,
+            "z": -0.43306630849838257
+        },
+        //lifetime: 100,
+        velocity: {
+            x: 0,
+            y: 0.1,
+            z: 0
+        },
+        "script": Script.resolvePath("portalGunClientEntity.js?" + Date.now()),
+        "shapeType": "compound",
+        "type": "Model",
+        "userData": "{\"grabbableKey\":{\"invertSolidWhileHeld\":true},\"wearable\":{\"joints\":{\"RightHand\":[{\"x\":0.1177130937576294,\"y\":0.12922893464565277,\"z\":0.08307232707738876},{\"x\":0.4934672713279724,\"y\":0.3605862259864807,\"z\":0.6394805908203125,\"w\":-0.4664038419723511}],\"LeftHand\":[{\"x\":0.09151676297187805,\"y\":0.13639454543590546,\"z\":0.09354984760284424},{\"x\":-0.19628101587295532,\"y\":0.6418180465698242,\"z\":0.2830369472503662,\"w\":0.6851521730422974}]}}}"
+    };
+
+    var lightProps = {
+        //lifetime: 100,
+        "color": {
+            "blue": 255,
+            "green": 166,
+            "red": 41
+        },
+        "cutoff": 90,
+        "dimensions": {
+            "x": 5.0777130126953125,
+            "y": 5.0777130126953125,
+            "z": 5.0777130126953125
+        },
+        "falloffRadius": 2.2000000476837158,
+        "intensity": 5,
+        "name": "Portal/GunLight",
+        "localPosition": {
+            x: 0,
+            y: 0.1,
+            z: 0.5
+        },
+        "type": "Light"
+    };
+
+    var gunData = {
+        red: {
+            modelURL: GUN_RED_MODEL_URL,
+            lightColor: {
+                red: 255,
+                green: 23,
+                blue: 96,
+            }
+        },
+        blue: {
+            modelURL: GUN_BLUE_MODEL_URL,
+            lightColor: {
+                red: 41,
+                green: 166,
+                blue: 255,
+            }
+        }
+    };
+
+    var inCooldown = false;
+
+    this.preload = function(entityID) {
+        this.entityID = entityID;
+    };
+
+    function spawnWeapons() {
+        if (inCooldown) {
+            return;
+        }
+
+        var position = Entities.getEntityProperties(this.entityID, 'position').position;
+
+        var userData = JSON.parse(gunProps.userData);
+        var colors = ['red', 'blue'];
+        for (var i = 0; i < colors.length; ++i) {
+            var color = colors[i];
+            gunProps.modelURL = gunData[color].modelURL;
+            gunProps.position = position;
+            userData.color = color;
+            gunProps.userData = JSON.stringify(userData);
+            var gunID = Entities.addEntity(gunProps);
+
+            lightProps.color = gunData[color].lightColor;
+            lightProps.parentID = gunID;
+            Entities.addEntity(lightProps);
+        }
+
+        inCooldown = true;
+        Script.setTimeout(function() {
+            inCooldown = false;
+        }, 2000);
+    }
+
+    this.startNearTrigger = spawnWeapons;
+    this.startFarTrigger = spawnWeapons;
+    this.clickDownOnEntity = spawnWeapons;
+});
diff --git a/hifi-content/huffman/ctf/models/portalgun.fbx b/hifi-content/huffman/ctf/models/portalgun.fbx
new file mode 120000
index 000000000..073c1557b
--- /dev/null
+++ b/hifi-content/huffman/ctf/models/portalgun.fbx
@@ -0,0 +1 @@
+../../../alan/dev/Pingportal-Gun-New.fbx
\ No newline at end of file
diff --git a/hifi-content/huffman/ctf/models/portalgun_blue.fbx b/hifi-content/huffman/ctf/models/portalgun_blue.fbx
new file mode 120000
index 000000000..073c1557b
--- /dev/null
+++ b/hifi-content/huffman/ctf/models/portalgun_blue.fbx
@@ -0,0 +1 @@
+../../../alan/dev/Pingportal-Gun-New.fbx
\ No newline at end of file
diff --git a/hifi-content/huffman/ctf/models/portalgun_collider.obj b/hifi-content/huffman/ctf/models/portalgun_collider.obj
new file mode 120000
index 000000000..8557ff2a3
--- /dev/null
+++ b/hifi-content/huffman/ctf/models/portalgun_collider.obj
@@ -0,0 +1 @@
+../../../alan/dev/Pingpong-Gun-New.obj
\ No newline at end of file
diff --git a/hifi-content/huffman/ctf/models/portalgun_red.fbx b/hifi-content/huffman/ctf/models/portalgun_red.fbx
new file mode 120000
index 000000000..b02853b30
--- /dev/null
+++ b/hifi-content/huffman/ctf/models/portalgun_red.fbx
@@ -0,0 +1 @@
+../../../alan/dev/PingPortal-Gun-red.fbx
\ No newline at end of file
diff --git a/hifi-content/huffman/ctf/origina_portal_gun.js b/hifi-content/huffman/ctf/origina_portal_gun.js
new file mode 100644
index 000000000..89bb5fa66
--- /dev/null
+++ b/hifi-content/huffman/ctf/origina_portal_gun.js
@@ -0,0 +1,210 @@
+//  pingPongGun.js
+//
+//  Script Type: Entity
+//  Created by James B. Pollack @imgntn on 9/21/2015
+//  Copyright 2015 High Fidelity, Inc.
+//  
+//  This script shoots a ping pong ball.
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+(function() {
+    var _this = this;
+
+    var SHOOTING_SOUND_URL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunFire02.wav';
+
+    function PingPongGun() {
+        return;
+    }
+
+    //if the trigger value goes below this value, reload the gun.
+    var RELOAD_THRESHOLD = 0.95;
+    var GUN_TIP_FWD_OFFSET = -1;
+    var GUN_TIP_UP_OFFSET = 0.12;
+    var GUN_FORCE = 20;
+    var BALL_RESTITUTION = 0.2;
+    var BALL_LINEAR_DAMPING = 0.1;
+    var BALL_DENSITY = 10000;
+    var BALL_GRAVITY = {
+        x: 0,
+        y: -4.8,
+        z: 0
+    };
+
+    var PING_PONG_GUN_GRAVITY = {
+        x: 0,
+        y: -10,
+        z: 0
+    };
+
+    var BALL_DIMENSIONS = {
+        x: 2.5,
+        y: 2.5,
+        z: 2.5
+    };
+
+    var BALL_ANGULAR_VEL = {
+        x: 2,
+        y: 3,
+        z: 1
+    };
+
+
+
+    var TRIGGER_CONTROLS = [
+        Controller.Standard.LT,
+        Controller.Standard.RT,
+    ];
+
+
+    PingPongGun.prototype = {
+        hand: null,
+        gunTipPosition: null,
+        canShoot: false,
+        canShootTimeout: null,
+
+        startEquip: function(entityID, args) {
+            this.hand = args[0] == "left" ? 0 : 1;
+        },
+
+        continueEquip: function(entityID, args) {
+            if (this.canShootTimeout !== null) {
+                Script.clearTimeout(this.canShootTimeout);
+            }
+            this.checkTriggerPressure(this.hand);
+        },
+
+        releaseEquip: function(entityID, args) {
+            var _this = this;
+            this.canShootTimeout = Script.setTimeout(function() {
+                _this.canShoot = false;
+            }, 250);
+        },
+
+        checkTriggerPressure: function(gunHand) {
+            this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[gunHand]);
+            if (this.triggerValue < RELOAD_THRESHOLD) {
+                this.canShoot = true;
+            } else if (this.triggerValue >= RELOAD_THRESHOLD && this.canShoot === true) {
+                var gunProperties = Entities.getEntityProperties(this.entityID, ["position", "rotation"]);
+                this.shootBall(gunProperties);
+                this.canShoot = false;
+            }
+
+            return;
+        },
+
+        shootBall: function(gunProperties) {
+            var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 180, 0)));
+            forwardVec = Vec3.normalize(forwardVec);
+            forwardVec = Vec3.multiply(forwardVec, GUN_FORCE);
+            var gunTipPosition = this.getGunTipPosition(gunProperties);
+
+            var projectileProperties = {
+                name: 'Glow-Projectile',
+                type: 'Model',
+                modelURL: "http://hifi-content.s3.amazonaws.com/alan/dev/Glow-ball-blue.fbx",
+                dimensions: BALL_DIMENSIONS,
+                damping: BALL_LINEAR_DAMPING,
+                gravity: BALL_GRAVITY,
+                restitution: BALL_RESTITUTION,
+                density: BALL_DENSITY,
+                dynamic: true,
+                rotation: gunProperties.rotation,
+                position: gunTipPosition,
+                gravity: PING_PONG_GUN_GRAVITY,
+                angularDamping: 0,
+                angularVelocity: BALL_ANGULAR_VEL,
+                velocity: forwardVec,
+                lifetime: 10,
+                collisionless: true,
+                visible: true,
+            };
+
+            var projectileID = Entities.addEntity(projectileProperties);
+
+
+            var portalProperties = {
+                name: 'Portal-Projectile',
+                type: 'Sphere',
+                dimensions: BALL_DIMENSIONS,
+                parentID: projectileID,
+                damping: BALL_LINEAR_DAMPING,
+                gravity: BALL_GRAVITY,
+                restitution: BALL_RESTITUTION,
+                density: BALL_DENSITY,
+                dynamic: false,
+                rotation: gunProperties.rotation,
+                position: gunTipPosition,
+                gravity: PING_PONG_GUN_GRAVITY,
+                angularDamping: 0,
+                angularVelocity: BALL_ANGULAR_VEL,
+                velocity: forwardVec,
+                lifetime: 10,
+                visible: false,
+                script: 'http://hifi-content.s3.amazonaws.com/alan/dev/Scripts/portal-lionsgate.js',
+                collisionless: true,
+            };
+
+            Entities.addEntity(portalProperties);
+
+
+            this.playSoundAtCurrentPosition(gunProperties.position);
+        },
+
+        playSoundAtCurrentPosition: function(position) {
+            var audioProperties = {
+                volume: 0.9,
+                position: position
+            };
+
+            Audio.playSound(this.SHOOTING_SOUND, audioProperties);
+        },
+
+        getGunTipPosition: function(properties) {
+            //the tip of the gun is going to be in a different place than the center, so we move in space relative to the model to find that position
+            var frontVector = Quat.getFront(properties.rotation);
+            var frontOffset = Vec3.multiply(frontVector, GUN_TIP_FWD_OFFSET);
+            var upVector = Quat.getUp(properties.rotation);
+            var upOffset = Vec3.multiply(upVector, GUN_TIP_UP_OFFSET);
+
+            var gunTipPosition = Vec3.sum(properties.position, frontOffset);
+            gunTipPosition = Vec3.sum(gunTipPosition, upOffset);
+
+            return gunTipPosition;
+        },
+
+        preload: function(entityID) {
+            this.entityID = entityID;
+            this.SHOOTING_SOUND = SoundCache.getSound(SHOOTING_SOUND_URL);
+            // this.createTipEntity(entityID);
+        },
+        createTipEntity: function(entityID) {
+            //for debugging where its going to shoot from
+            var gunProperties = Entities.getEntityProperties(entityID, ["position", "rotation"]);
+
+            var tipProps = {
+                name: 'Ping pong tip test',
+                dimensions: {
+                    x: 0.1,
+                    y: 0.1,
+                    z: 0.1
+                },
+                color: {
+                    red: 0,
+                    green: 255,
+                    blue: 0
+                },
+                type: 'Box',
+                parentID: entityID,
+                position: this.getGunTipPosition(gunProperties)
+            };
+            var tip = Entities.addEntity(tipProps);
+        }
+
+    };
+
+    // entity scripts should return a newly constructed object of our type
+    return new PingPongGun();
+});
\ No newline at end of file
diff --git a/hifi-content/huffman/ctf/portalBulletClientEntity.js b/hifi-content/huffman/ctf/portalBulletClientEntity.js
new file mode 100644
index 000000000..0b5e7f860
--- /dev/null
+++ b/hifi-content/huffman/ctf/portalBulletClientEntity.js
@@ -0,0 +1,47 @@
+(function() {
+    this.preload = function(entityID) {
+        print("Loading portal bullet script");
+
+        this.teleportSound = SoundCache.getSound(Script.resolvePath("sounds/teleport.raw"));
+        this.portalTargetLocation = undefined;
+
+        var userData = Entities.getEntityProperties(entityID, 'userData').userData;
+        try {
+            this.portalTargetLocation = JSON.parse(userData).portalTargetLocation;
+        } catch (e) {
+            this.portalTargetLocation = undefined;
+        }
+
+        if (this.portalTargetLocation === undefined) {
+            print("ERROR, could not find portalTargetLocation in userData");
+        } else {
+            print("Portal target location is: ", this.portalTargetLocation);
+        }
+    };
+
+    this.enterEntity = function(entityID) {
+        print("Entered bullet entity, the destination is " + this.portalTargetLocation);
+
+        if (this.teleportSound.downloaded) {
+            var position = Entities.getEntityProperties(this.entityID, 'position').position;
+            Audio.playSound(this.teleportSound, {
+                position: position,
+                volume: 0.40,
+                localOnly: true
+            });
+        }
+
+        if (this.portalTargetLocation !== undefined) {
+            print("Teleporting to " + this.portalTargetLocation);
+            Window.location = this.portalTargetLocation;
+        }
+
+        // Notify any instances of the ball that we have been hit ensuring that
+        // the ball will be dropped if we are holding it.
+        Messages.sendLocalMessage("Portal-Game", "hit");
+    };
+
+    this.unload = function() {
+        print("unloading teleport script");
+    };
+});
diff --git a/hifi-content/huffman/ctf/portalGunClientEntity.js b/hifi-content/huffman/ctf/portalGunClientEntity.js
new file mode 100644
index 000000000..b7c43e3ff
--- /dev/null
+++ b/hifi-content/huffman/ctf/portalGunClientEntity.js
@@ -0,0 +1,222 @@
+//  pingPongGun.js
+//
+//  Script Type: Entity
+//  Created by James B. Pollack @imgntn on 9/21/2015
+//  Copyright 2015 High Fidelity, Inc.
+//  
+//  This script shoots a ping pong ball.
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+(function() {
+    var TRIGGER_THRESHOLD = 0.3;
+
+    var BULLET_BLUE_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Glow-ball-blue.fbx";
+    var BULLET_RED_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Glow-ball-red.fbx";
+
+    var GUN_LOAD_SOUND_URL = "https://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunLoad02.wav";
+    var GUN_FIRE1_SOUND_URL = "https://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunFire01.wav";
+    var GUN_FIRE2_SOUND_URL = "https://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunFire02.wav";
+    var GUN_FIRE3_SOUND_URL = "https://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunFire03.wav";
+
+    var GUN_TIP_FWD_OFFSET = -1;
+    var GUN_TIP_UP_OFFSET = 0.12;
+    var GUN_FORCE = 20;
+    var BALL_RESTITUTION = 0.2;
+    var BALL_LINEAR_DAMPING = 0.1;
+    var BALL_DENSITY = 10000;
+
+    var BALL_GRAVITY = {
+        x: 0,
+        y: -10,
+        z: 0
+    };
+
+    var BALL_DIMENSIONS = {
+        x: 2.5,
+        y: 2.5,
+        z: 2.5
+    };
+
+    var BALL_COLLIDER_DIMENSIONS = {
+        x: 0.94,
+        y: 2.0,
+        z: 0.94
+    };
+
+    var BALL_ANGULAR_VEL = {
+        x: 2,
+        y: 3,
+        z: 1
+    };
+
+    var TRIGGER_CONTROLS = [
+        Controller.Standard.LT,
+        Controller.Standard.RT
+    ];
+
+    function PortalGun() {
+    }
+
+    PortalGun.prototype = {
+        hand: null,
+        gunTipPosition: null,
+        cooldownActive: false,
+
+        preload: function(entityID) {
+            this.entityID = entityID;
+            this.gunFireSound = SoundCache.getSound(GUN_FIRE1_SOUND_URL);
+            this.gunLoadSound = SoundCache.getSound(GUN_LOAD_SOUND_URL);
+
+            this.hasReleasedInitialTriggerPress = false;
+
+            this.color = 'red';
+
+            var userData = Entities.getEntityProperties(entityID, 'userData').userData;
+            try {
+                userData = JSON.parse(userData);
+                if (userData.color === 'red' || userData.color === 'blue') {
+                    this.color = userData.color;
+                } else {
+                    print("ERROR, invalid color:", userData.color);
+                }
+            } catch (e) {
+                print("ERROR, could not find gun color");
+            }
+        },
+        startEquip: function(entityID, args) {
+            this.hand = args[0] === "left" ? 0 : 1;
+        },
+        continueEquip: function(entityID, args) {
+            if (this.cooldownActive) {
+                return;
+            }
+
+            var triggerValue = Controller.getValue(TRIGGER_CONTROLS[this.hand]);
+            if (triggerValue > TRIGGER_THRESHOLD) {
+                if (this.hasReleasedInitialTriggerPress) {
+                    this.shootBall();
+                }
+            } else {
+                this.hasReleasedInitialTriggerPress = true;
+            }
+        },
+        releaseEquip: function(entityID, args) {
+        },
+        shootBall: function() {
+            if (this.cooldownActive) {
+                print("Not allowing portal bullet to be shot while cooldown active");
+                return;
+            }
+            Controller.triggerHapticPulse(10.0, 0.5, this.hand);
+
+            var gunProperties = Entities.getEntityProperties(this.entityID, ["position", "rotation"]);
+
+            var gunTipPosition = this.getGunTipPosition(gunProperties);
+
+            var audioProperties = {
+                volume: 0.9,
+                position: gunTipPosition,
+                localOnly: true
+            };
+
+            Audio.playSound(this.gunFireSound, audioProperties);
+
+            var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 180, 0)));
+            forwardVec = Vec3.normalize(forwardVec);
+            forwardVec = Vec3.multiply(forwardVec, GUN_FORCE);
+
+            var projectileProperties = {
+                name: 'CTF/PortalBullet',
+                type: 'Model',
+                modelURL: this.color === 'blue' ? BULLET_BLUE_MODEL_URL : BULLET_RED_MODEL_URL,
+                dimensions: BALL_DIMENSIONS,
+                damping: BALL_LINEAR_DAMPING,
+                gravity: BALL_GRAVITY,
+                restitution: BALL_RESTITUTION,
+                density: BALL_DENSITY,
+                dynamic: true,
+                rotation: gunProperties.rotation,
+                position: gunTipPosition,
+                angularDamping: 0,
+                angularVelocity: BALL_ANGULAR_VEL,
+                velocity: forwardVec,
+                lifetime: 10,
+                collisionless: true,
+                visible: true
+            };
+            var projectileID = Entities.addEntity(projectileProperties);
+
+            var portalProperties = {
+                name: 'CTF/PortalCollider',
+                type: 'Sphere',
+                localPosition: { x: 0, y: 0, z: 0 },
+                dimensions: BALL_DIMENSIONS,
+                parentID: projectileID,
+                dynamic: false,
+                lifetime: 10,
+                visible: false,
+                script: Script.resolvePath("portalBulletClientEntity.js"),
+                collisionless: true,
+                userData: JSON.stringify({
+                    //portalTargetLocation: "hifi://lionsgate.highfidelity.io/-104.376,-0.496867,-8.28224/0,0.721841,0,0.692059"
+                    portalTargetLocation: "/16.0555,-0.372284,18.5259/0,0.631228,0,0.775597"
+                })
+            };
+            Entities.addEntity(portalProperties);
+
+            var self = this;
+            this.cooldownActive = true;
+            Script.setTimeout(function() {
+                var gunProperties = Entities.getEntityProperties(self.entityID, ["position", "rotation"]);
+                var gunTipPosition = self.getGunTipPosition(gunProperties);
+                var audioProperties = {
+                    volume: 0.9,
+                    position: gunTipPosition,
+                    localOnly: true
+                };
+                Audio.playSound(self.gunLoadSound, audioProperties);
+                self.cooldownActive = false;
+            }, 1000);
+        },
+        getGunTipPosition: function(properties) {
+            // the tip of the gun is going to be in a different place than the center,
+            // so we move in space relative to the model to find that position
+            var frontVector = Quat.getFront(properties.rotation);
+            var frontOffset = Vec3.multiply(frontVector, GUN_TIP_FWD_OFFSET);
+            var upVector = Quat.getUp(properties.rotation);
+            var upOffset = Vec3.multiply(upVector, GUN_TIP_UP_OFFSET);
+
+            var gunTipPosition = Vec3.sum(properties.position, frontOffset);
+            gunTipPosition = Vec3.sum(gunTipPosition, upOffset);
+
+            return gunTipPosition;
+        },
+        createTipEntity: function(entityID) {
+            // for debugging where its going to shoot from
+            var gunProperties = Entities.getEntityProperties(entityID, ["position", "rotation"]);
+
+            var tipProps = {
+                name: 'Ping pong tip test',
+                dimensions: {
+                    x: 0.1,
+                    y: 0.1,
+                    z: 0.1
+                },
+                color: {
+                    red: 0,
+                    green: 255,
+                    blue: 0
+                },
+                type: 'Box',
+                parentID: entityID,
+                position: this.getGunTipPosition(gunProperties)
+            };
+            Entities.addEntity(tipProps);
+        }
+    };
+
+    // entity scripts should return a newly varructed object of our type
+    return new PortalGun();
+});
diff --git a/hifi-content/huffman/ctf/portalgun.json b/hifi-content/huffman/ctf/portalgun.json
new file mode 100644
index 000000000..cbd6402a4
--- /dev/null
+++ b/hifi-content/huffman/ctf/portalgun.json
@@ -0,0 +1,81 @@
+{
+    "Entities": [
+        {
+            "clientOnly": 0,
+            "collisionsWillMove": 1,
+            "compoundShapeURL": "http://hifi-production.s3.amazonaws.com/tutorials/pingPongGun/Pingpong-Gun-New.obj",
+            "created": "2016-11-04T22:25:04Z",
+            "dimensions": {
+                "x": 0.17742760479450226,
+                "y": 0.38749998807907104,
+                "z": 0.99309998750686646
+            },
+            "dynamic": 1,
+            "gravity": {
+                "x": 0,
+                "y": -5,
+                "z": 0
+            },
+            "id": "{a871719d-051d-4899-81f8-f624c04c3e3a}",
+            "modelURL": "http://hifi-content.s3.amazonaws.com/alan/dev/Pingportal-Gun-New.fbx?1",
+            "name": "Tutorial Ping Pong Gun",
+            "owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
+            "queryAACube": {
+                "scale": 1.0806869268417358,
+                "x": -0.54034346342086792,
+                "y": -0.54034346342086792,
+                "z": -0.54034346342086792
+            },
+            "rotation": {
+                "w": -0.14616614580154419,
+                "x": -0.68838024139404297,
+                "y": 0.69466698169708252,
+                "z": 0.14915692806243896
+            },
+            "script": "http://hifi-content.s3.amazonaws.com/alan/dev/Scripts/ping-portal-welcome.js?3",
+            "shapeType": "compound",
+            "type": "Model",
+            "userData": "{\"grabbableKey\":{\"invertSolidWhileHeld\":true},\"wearable\":{\"joints\":{\"RightHand\":[{\"x\":0.1177130937576294,\"y\":0.12922893464565277,\"z\":0.08307232707738876},{\"x\":0.4934672713279724,\"y\":0.3605862259864807,\"z\":0.6394805908203125,\"w\":-0.4664038419723511}],\"LeftHand\":[{\"x\":0.09151676297187805,\"y\":0.13639454543590546,\"z\":0.09354984760284424},{\"x\":-0.19628101587295532,\"y\":0.6418180465698242,\"z\":0.2830369472503662,\"w\":0.6851521730422974}]}}}"
+        },
+        {
+            "clientOnly": 0,
+            "color": {
+                "blue": 255,
+                "green": 166,
+                "red": 41
+            },
+            "created": "2016-11-04T22:55:39Z",
+            "cutoff": 90,
+            "dimensions": {
+                "x": 5.0777130126953125,
+                "y": 5.0777130126953125,
+                "z": 5.0777130126953125
+            },
+            "falloffRadius": 1.7000000476837158,
+            "id": "{a240a5b9-8ec5-46f7-a443-fd99ee08ba33}",
+            "intensity": 3.2999999523162842,
+            "name": "PingPortal-Light",
+            "owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
+            "parentID": "{a871719d-051d-4899-81f8-f624c04c3e3a}",
+            "position": {
+                "x": -0.071898072957992554,
+                "y": 0.1922331303358078,
+                "z": 0.59060537815093994
+            },
+            "queryAACube": {
+                "scale": 8.7948570251464844,
+                "x": 6.5513162612915039,
+                "y": -4.9521479606628418,
+                "z": -150.72532653808594
+            },
+            "rotation": {
+                "w": -0.14616614580154419,
+                "x": 0.68838024139404297,
+                "y": -0.69466698169708252,
+                "z": -0.14915692806243896
+            },
+            "type": "Light"
+        }
+    ],
+    "Version": 64
+}
diff --git a/hifi-content/huffman/ctf/sounds/gunFire.wav b/hifi-content/huffman/ctf/sounds/gunFire.wav
new file mode 100644
index 000000000..88b11e741
--- /dev/null
+++ b/hifi-content/huffman/ctf/sounds/gunFire.wav
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:99e52a695d2477a48f71da9f15f40f02ec1073768eba8e26ed0cda07c34e93cb
+size 145056
diff --git a/hifi-content/huffman/ctf/sounds/pong_sound.wav b/hifi-content/huffman/ctf/sounds/pong_sound.wav
new file mode 100644
index 000000000..388d1bad1
--- /dev/null
+++ b/hifi-content/huffman/ctf/sounds/pong_sound.wav
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0bab5297e882dd92ca7fcb5f1e043386249d28cc5a013fc7a48c2660386c81aa
+size 46926
diff --git a/hifi-content/huffman/ctf/sounds/teleport.raw b/hifi-content/huffman/ctf/sounds/teleport.raw
new file mode 100644
index 0000000000000000000000000000000000000000..7ee3b4ce483261c37f95535d4f45583df911c396
GIT binary patch
literal 106592
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
ZhYue<eE9I;!-o$aK79D_;loFA{4d%u-o^j`

literal 0
HcmV?d00001

diff --git a/hifi-content/huffman/ctf/spawnPortalGun.js b/hifi-content/huffman/ctf/spawnPortalGun.js
new file mode 100644
index 000000000..531216a36
--- /dev/null
+++ b/hifi-content/huffman/ctf/spawnPortalGun.js
@@ -0,0 +1,99 @@
+var GUN_RED_MODEL_URL = Script.resolvePath("models/portalgun_red.fbx");
+var GUN_BLUE_MODEL_URL = Script.resolvePath("models/portalgun_blue.fbx");
+
+var gunProps = {
+    "collisionsWillMove": 1,
+    "compoundShapeURL": Script.resolvePath("models/portalgun_collider.obj"),
+    "dimensions": {
+        "x": 0.17742760479450226,
+        "y": 0.38749998807907104,
+        "z": 0.99309998750686646
+    },
+    "dynamic": 1,
+    "gravity": {
+        "x": 0,
+        "y": -5,
+        "z": 0
+    },
+    "modelURL": Script.resolvePath("models/portalgun_red.fbx"),
+    "name": "Portal/Gun",
+    "position": {
+        "x": 1.4289360046386719,
+        "y": 0,
+        "z": 1.4532890319824219
+    },
+    "rotation": {
+        "w": 0.51259636878967285,
+        "x": -0.5248645544052124,
+        "y": 0.5236133337020874,
+        "z": -0.43306630849838257
+    },
+    lifetime: 100,
+    velocity: {
+        x: 0,
+        y: 0.5,
+        z: 0
+    },
+    "script": Script.resolvePath("portalGunClientEntity.js?" + Date.now()),
+    "shapeType": "compound",
+    "type": "Model",
+    "userData": "{\"grabbableKey\":{\"invertSolidWhileHeld\":true},\"wearable\":{\"joints\":{\"RightHand\":[{\"x\":0.1177130937576294,\"y\":0.12922893464565277,\"z\":0.08307232707738876},{\"x\":0.4934672713279724,\"y\":0.3605862259864807,\"z\":0.6394805908203125,\"w\":-0.4664038419723511}],\"LeftHand\":[{\"x\":0.09151676297187805,\"y\":0.13639454543590546,\"z\":0.09354984760284424},{\"x\":-0.19628101587295532,\"y\":0.6418180465698242,\"z\":0.2830369472503662,\"w\":0.6851521730422974}]}}}"
+};
+
+var lightProps = {
+    lifetime: 100,
+    "color": {
+        "blue": 255,
+        "green": 166,
+        "red": 41
+    },
+    "cutoff": 90,
+    "dimensions": {
+        "x": 5.0777130126953125,
+        "y": 5.0777130126953125,
+        "z": 5.0777130126953125
+    },
+    "falloffRadius": 2.2000000476837158,
+    "intensity": 5,
+    "name": "Portal/GunLight",
+    "localPosition": {
+        x: 0,
+        y: 0.1,
+        z: 0.5
+    },
+    "type": "Light"
+};
+
+var userData = JSON.parse(gunProps.userData);
+var gunData = {
+    red: {
+        modelURL: GUN_RED_MODEL_URL,
+        lightColor: {
+            red: 255,
+            green: 23,
+            blue: 96,
+        }
+    },
+    blue: {
+        modelURL: GUN_BLUE_MODEL_URL,
+        lightColor: {
+            red: 41,
+            green: 166,
+            blue: 255,
+        }
+    }
+};
+var models = [GUN_RED_MODEL_URL, GUN_BLUE_MODEL_URL];
+var colors = ['red', 'blue'];
+for (var i = 0; i < colors.length; ++i) {
+    var color = colors[i];
+    gunProps.modelURL = gunData[color].modelURL;
+    gunProps.position = MyAvatar.position;
+    userData.color = color;
+    gunProps.userData = JSON.stringify(userData);
+    var gunID = Entities.addEntity(gunProps);
+
+    lightProps.color = gunData[color].lightColor;
+    lightProps.parentID = gunID;
+    Entities.addEntity(lightProps);
+}
diff --git a/hifi-content/huffman/ctf/utils.js b/hifi-content/huffman/ctf/utils.js
new file mode 100644
index 000000000..4cc179b81
--- /dev/null
+++ b/hifi-content/huffman/ctf/utils.js
@@ -0,0 +1,93 @@
+//
+//  utils.js
+//  examples/baseball/
+//
+//  Created by Ryan Huffman on Nov 9, 2015
+//  Copyright 2015 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+randomInt = function(low, high) {
+    print("low, high", low, high);
+    return Math.floor(randomFloat(low, high));
+};
+
+randomFloat = function(low, high) {
+    if (high === undefined) {
+        high = low;
+        low = 0;
+    }
+    return low + Math.random() * (high - low);
+};
+
+randomColor = function(redMin, redMax, greenMin, greenMax, blueMin, blueMax) {
+    return {
+        red: Math.ceil(randomInt(redMin, redMax)),
+        green: Math.ceil(randomInt(greenMin, greenMax)),
+        blue: Math.ceil(randomInt(blueMin, blueMax)),
+    }
+};
+
+randomVec3 = function(xMin, xMax, yMin, yMax, zMin, zMax) {
+    return {
+        x: randomFloat(xMin, xMax),
+        y: randomFloat(yMin, yMax),
+        z: randomFloat(zMin, zMax),
+    }
+};
+
+getSounds = function(soundURLs) {
+    var sounds = [];
+    for (var i = 0; i < soundURLs.length; ++i) {
+        sounds.push(SoundCache.getSound(soundURLs[i], false));
+    }
+    return sounds;
+};
+
+playRandomSound = function(sounds, options) {
+    if (options === undefined) {
+        options = {
+            volume: 1.0,
+            position: MyAvatar.position,
+        }
+    }
+    return Audio.playSound(sounds[randomInt(sounds.length)], options);
+}
+
+shallowCopy = function(obj) {
+    var copy = {}
+    for (var key in obj) {
+        copy[key] = obj[key];
+    }
+    return copy;
+}
+
+findEntity = function(properties, searchRadius) {
+    var entities = findEntities(properties, searchRadius);
+    return entities.length > 0 ? entities[0] : null;
+}
+
+// Return all entities with properties `properties` within radius `searchRadius`
+findEntities = function(properties, searchRadius) {
+    var entities = Entities.findEntities(MyAvatar.position, searchRadius);
+    var matchedEntities = [];
+    var keys = Object.keys(properties);
+    for (var i = 0; i < entities.length; ++i) {
+        var match = true;
+        var candidateProperties = Entities.getEntityProperties(entities[i], keys);
+        for (var key in properties) {
+            if (candidateProperties[key] != properties[key]) {
+                // This isn't a match, move to next entity
+                match = false;
+                break;
+            }
+        }
+        if (match) {
+            matchedEntities.push(entities[i]);
+        }
+    }
+
+    return matchedEntities;
+}
diff --git a/hifi-content/huffman/essTest.js b/hifi-content/huffman/essTest.js
new file mode 100644
index 000000000..698873da6
--- /dev/null
+++ b/hifi-content/huffman/essTest.js
@@ -0,0 +1,9 @@
+(function() {
+    print("Inside ctor");
+    this.preload = function() {
+        print("inside preload");
+    }
+    this.unload = function() {
+        print("inside preload");
+    }
+});