}
+ * }
+ */
+
+class PlayState {
+ constructor() {
+ this._state = {
+ variables: {}
+ };
+
+ this.variableGet = this.variableGet.bind(this);
+ window.messageBus.ext.subscribe("var/+/get", this.variableGet);
+ this.variableSet = this.variableSet.bind(this);
+ window.messageBus.ext.subscribe("var/+/set", this.variableSet);
+ this.variableSubGet = this.variableSubGet.bind(this);
+ window.messageBus.ext.subscribe("var/+/get/sub", this.variableSubGet);
+ }
+
+ variableGet(topic, value) {
+ const id = MessageBus.extractLevel(topic, 2);
+ if (id != null)
+ window.messageBus.ext.publish("var/" + id, this._state.variables[id]);
+ }
+
+ variableSubGet(topic, value) {
+ // console.log("sub solicitado: " + topic + ";" + value);
+ const id = MessageBus.extractLevel(topic, 2);
+ if (id != null) {
+ let result = null;
+ if (this._state.variables[id])
+ for (let v in this._state.variables[id])
+ if (this._state.variables[id][v].content == value)
+ result = this._state.variables[id][v].state;
+ // console.log("-- sub resultado: " + result);
+ window.messageBus.ext.publish("var/" + id + "/sub", result);
+ }
+ }
+
+ variableSet(topic, value) {
+ const id = MessageBus.extractLevel(topic, 2);
+ if (id != null)
+ this._state.variables[id] = value;
+ // console.log("Variables updated:");
+ // console.log(this._state);
+ }
+}
\ No newline at end of file
diff --git a/player/js/tracker.js b/player/js/tracker.js
new file mode 100644
index 0000000..0b97fc7
--- /dev/null
+++ b/player/js/tracker.js
@@ -0,0 +1,85 @@
+/**
+ *
+ */
+
+class Tracker {
+ constructor() {
+ // this._server = server;
+ this._variables = {};
+ this._groupInput = null;
+
+ this.inputReady = this.inputReady.bind(this);
+ window.messageBus.ext.subscribe("var/+/input/ready", this.inputReady);
+ this.groupinputReady = this.groupinputReady.bind(this);
+ window.messageBus.ext.subscribe("var/+/group_input/ready", this.groupinputReady);
+ this.subinputReady = this.subinputReady.bind(this);
+ window.messageBus.ext.subscribe("var/+/subinput/ready", this.subinputReady);
+ this.inputTyped = this.inputTyped.bind(this);
+ window.messageBus.ext.subscribe("var/+/typed", this.inputTyped);
+ this.inputChanged = this.inputChanged.bind(this);
+ window.messageBus.ext.subscribe("var/+/changed", this.inputChanged);
+ this.stateChanged = this.stateChanged.bind(this);
+ window.messageBus.ext.subscribe("var/+/state_changed", this.stateChanged);
+
+ this.submitVariables = this.submitVariables.bind(this);
+ window.messageBus.ext.subscribe("control/input/submit", this.submitVariables);
+ }
+
+ inputReady(topic, message) {
+ this._updateVariable(topic, "");
+ // console.log("input: " + message.value);
+ }
+
+ groupinputReady(topic, message) {
+ this._updateVariable(topic, {});
+ this._groupInput = MessageBus.extractLevel(topic, 2);
+ // console.log("input: " + message.context);
+ }
+
+ subinputReady(topic, message) {
+ // console.log("variables");
+ // console.log(this._variables);
+
+ if (this._groupInput != null) {
+ const id = MessageBus.extractLevel(topic, 2);
+ this._variables[this._groupInput][id] =
+ {content: message.content, state: " "};
+ }
+ }
+
+ inputTyped(topic, message) {
+ this._updateVariable(topic, message.value);
+ // console.log("input: " + message.value);
+ }
+
+ inputChanged(topic, message) {
+ this._updateVariable(topic, message.value);
+ // console.log("input: " + message.value);
+ }
+
+ stateChanged(topic, message) {
+ if (this._groupInput != null) {
+ const id = MessageBus.extractLevel(topic, 2);
+ this._variables[this._groupInput][id].state = message.state;
+ }
+
+ // console.log("variables");
+ // console.log(this._variables);
+ }
+
+ submitVariables(topic, message) {
+ for (let v in this._variables)
+ window.messageBus.ext.publish("var/" + v + "/set", this._variables[v]);
+ // console.log("variavel: " + v + " -- " + this._variables[v]);
+ // this._server.recordInput(v, this._variables[v]);
+ }
+
+ _updateVariable(topic, value) {
+ let v = MessageBus.extractLevel(topic, 2);
+ // /^\/var\/(\w+)\//.exec(topic);
+ if (v != null) {
+ this._variables[v] = value;
+ // console.log("update variable " + v + " with " + value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/shared/images/bubble-landscape.png b/shared/images/bubble-landscape.png
new file mode 100644
index 0000000..2836a26
Binary files /dev/null and b/shared/images/bubble-landscape.png differ
diff --git a/shared/images/bubble-portrait.png b/shared/images/bubble-portrait.png
new file mode 100644
index 0000000..f3e8564
Binary files /dev/null and b/shared/images/bubble-portrait.png differ
diff --git a/shared/images/call-the-supervisor.svg b/shared/images/call-the-supervisor.svg
new file mode 100644
index 0000000..8e8f196
--- /dev/null
+++ b/shared/images/call-the-supervisor.svg
@@ -0,0 +1,88 @@
+
+
+
+
diff --git a/shared/images/doctor-icon.png b/shared/images/doctor-icon.png
new file mode 100644
index 0000000..3b373e0
Binary files /dev/null and b/shared/images/doctor-icon.png differ
diff --git a/shared/images/doctor.png b/shared/images/doctor.png
new file mode 100644
index 0000000..a8c9ec3
Binary files /dev/null and b/shared/images/doctor.png differ
diff --git a/shared/images/entrance.jpg b/shared/images/entrance.jpg
new file mode 100644
index 0000000..1dd4be7
Binary files /dev/null and b/shared/images/entrance.jpg differ
diff --git a/shared/images/generate-hypothesis.svg b/shared/images/generate-hypothesis.svg
new file mode 100644
index 0000000..57d3183
--- /dev/null
+++ b/shared/images/generate-hypothesis.svg
@@ -0,0 +1,89 @@
+
+
+
+
diff --git a/shared/images/icon-back.svg b/shared/images/icon-back.svg
new file mode 100644
index 0000000..63a7be8
--- /dev/null
+++ b/shared/images/icon-back.svg
@@ -0,0 +1,77 @@
+
+
+
+
diff --git a/shared/images/jacinto-icon.png b/shared/images/jacinto-icon.png
new file mode 100644
index 0000000..1662c3c
Binary files /dev/null and b/shared/images/jacinto-icon.png differ
diff --git a/shared/images/jacinto.png b/shared/images/jacinto.png
new file mode 100644
index 0000000..4f4a65f
Binary files /dev/null and b/shared/images/jacinto.png differ
diff --git a/shared/images/mono-slide.svg b/shared/images/mono-slide.svg
new file mode 100644
index 0000000..526a6ea
--- /dev/null
+++ b/shared/images/mono-slide.svg
@@ -0,0 +1,127 @@
+
+
diff --git a/shared/images/more-information.svg b/shared/images/more-information.svg
new file mode 100644
index 0000000..637071c
--- /dev/null
+++ b/shared/images/more-information.svg
@@ -0,0 +1,80 @@
+
+
+
+
diff --git a/shared/images/nurse-icon.png b/shared/images/nurse-icon.png
new file mode 100644
index 0000000..54bbf99
Binary files /dev/null and b/shared/images/nurse-icon.png differ
diff --git a/shared/images/nurse.png b/shared/images/nurse.png
new file mode 100644
index 0000000..3e57884
Binary files /dev/null and b/shared/images/nurse.png differ
diff --git a/shared/images/tablet.svg b/shared/images/tablet.svg
new file mode 100644
index 0000000..efb362a
--- /dev/null
+++ b/shared/images/tablet.svg
@@ -0,0 +1,66 @@
+
+
+
+
diff --git a/src/adonisjs/.env.example b/src/adonisjs/.env.example
index 6a2fb47..d77fe5c 100644
--- a/src/adonisjs/.env.example
+++ b/src/adonisjs/.env.example
@@ -2,17 +2,13 @@ HOST=127.0.0.1
PORT=3333
NODE_ENV=development
APP_URL=http://${HOST}:${PORT}
-
CACHE_VIEWS=false
-
APP_KEY=
-
DB_CONNECTION=sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
-DB_USER=root
+DB_USER=
DB_PASSWORD=
-DB_DATABASE=adonis
-
+DB_DATABASE=
SESSION_DRIVER=cookie
HASH_DRIVER=bcrypt
diff --git a/src/adonisjs/.gitignore b/src/adonisjs/.gitignore
index 1e91f57..cf6b72c 100644
--- a/src/adonisjs/.gitignore
+++ b/src/adonisjs/.gitignore
@@ -1,7 +1,7 @@
# Node modules
node_modules
package-lock.json
-
+artifacts
# Adonis directory for storing tmp files
tmp
diff --git a/src/adonisjs/README.md b/src/adonisjs/README.md
deleted file mode 100644
index d78d10e..0000000
--- a/src/adonisjs/README.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# Adonis fullstack application
-
-This is the fullstack boilerplate for AdonisJs, it comes pre-configured with.
-
-1. Bodyparser
-2. Session
-3. Authentication
-4. Web security middleware
-5. CORS
-6. Edge template engine
-7. Lucid ORM
-8. Migrations and seeds
-
-## Setup
-
-Use the adonis command to install the blueprint
-
-```bash
-adonis new yardstick
-```
-
-or manually clone the repo and then run `npm install`.
-
-
-### Migrations
-
-Run the following command to run startup migrations.
-
-```js
-adonis migration:run
-```
diff --git a/src/adonisjs/app/Controllers/Http/AuthController.js b/src/adonisjs/app/Controllers/Http/AuthController.js
index 798383c..a0a6b1a 100644
--- a/src/adonisjs/app/Controllers/Http/AuthController.js
+++ b/src/adonisjs/app/Controllers/Http/AuthController.js
@@ -10,12 +10,18 @@ class AuthController {
if (await auth.attempt(email, password)) {
let user = await User.findBy('email', email)
let token = await auth.generate(user)
+
+ let authenticatedUser = new User()
+ authenticatedUser.id = user.id
+ authenticatedUser.email = user.email
+ authenticatedUser.username = user.username
- Object.assign(user, token)
- return response.json(user)
+ Object.assign(authenticatedUser, token)
+ return response.json(authenticatedUser)
}
}
catch (e) {
+ console.log(e)
return response.status(e.status).json({ message: e.message })
}
}
diff --git a/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js b/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js
new file mode 100644
index 0000000..76ebaf2
--- /dev/null
+++ b/src/adonisjs/app/Controllers/Http/v1/ArtifactController.js
@@ -0,0 +1,74 @@
+'use strict'
+
+const Helpers = use('Helpers')
+const Artifact = use('App/Models/v1/Artifact');
+const Case = use('App/Models/v1/Case');
+const Env = use('Env')
+const uuid = require('uuid/v4');
+
+class ArtifactController {
+
+ constructor(){
+
+ // See this for more on MIM types: https://docs.openx.com/Content/publishers/adunit_linearvideo_mime_types.html
+ this.validationOptions = {
+ size: '100mb',
+ types: ['image','video'],
+ extnames: ['png', 'jpg', 'jpge', 'gif','mp4','avi', '.wmv']
+ }
+
+ this.relativePath = '/artifacts/'
+
+
+ }
+
+ async store({ request, auth, response }) {
+
+
+ const file = request.file('file', this.validationOptions)
+ const caseID = request.input('case_id', null)
+
+ const artifactID = await uuid()
+ const artifactFileName = artifactID + "." + file.extname
+ const fsPath = Helpers.publicPath(this.relativePath)
+
+
+ await file.move(fsPath, {name: artifactFileName, overwrite: false})
+
+ if (!file.moved())
+ return file.error()
+
+
+
+ var linkedCase = await Case.find(caseID)
+
+
+
+ const artifact = new Artifact()
+ artifact.fs_path = fsPath + artifactFileName
+ artifact.relative_path = this.relativePath + artifactFileName
+ artifact.case_id = linkedCase != null ? linkedCase.id : linkedCase;
+ await auth.user.artifacts().save(artifact)
+
+ const base_url = Env.getOrFail('APP_URL')
+
+
+
+ return response.status(200).json({ message: "Artifact successfully stored",
+ filename: artifactFileName,
+ case: linkedCase,
+ size_in_bytes: file.size,
+ type: file.type,
+ subtype: file.subtype,
+ extension: file.extname,
+ status: file.status,
+ relative_path: artifact.relative_path,
+ url: base_url+artifact.relative_path
+
+ })
+
+ }
+
+}
+
+module.exports = ArtifactController
diff --git a/src/adonisjs/app/Controllers/Http/v1/CaseController.js b/src/adonisjs/app/Controllers/Http/v1/CaseController.js
index 045f56e..6d1312f 100644
--- a/src/adonisjs/app/Controllers/Http/v1/CaseController.js
+++ b/src/adonisjs/app/Controllers/Http/v1/CaseController.js
@@ -4,46 +4,31 @@
/** @typedef {import('@adonisjs/framework/src/Response')} Response */
/** @typedef {import('@adonisjs/framework/src/View')} View */
+const User = use('App/Models/v1/User');
const Case = use('App/Models/v1/Case');
-const Drive = use('Drive');
+const CaseVersion = use('App/Models/v1/CaseVersion')
-const uuidv1 = require('uuid/v1');
const fs = require('fs');
-const fse = require('fs-extra')
-var dateFormat = require('dateformat');
+const PLAYER_DIR = "../../player/"
-const DIR_MODELS = "../../models/"
-const DIR_CASES = "../../cases/";
-const FILE_CASE_NAME = "case";
-const FILE_CASE_EXTENSION = ".md";
-const FILE_CASE = FILE_CASE_NAME + FILE_CASE_EXTENSION;
-
-let BLANK_MODEL = "blank"
-let TEMPORARY_CASE = "_temporary"
-
-const DIR_PLAYER = "../../../harena-space/player/"
-const FILE_PLAYER = "index.html"
-const DIR_INFRA = "../infra/"
-/**
- * Resourceful controller for interacting with cases
- */
+/** * Resourceful controller for interacting with cases */
class CaseController {
- /**
- * Show a list of all cases.
- * GET cases
- *
- * @param {object} ctx
- * @param {Request} ctx.request
- * @param {Response} ctx.response
- * @param {View} ctx.view
- */
- async index({ response }) {
+ /** Show a list of all cases */
+ async index({ request, response }) {
try {
- console.log('index')
- let cases = await Case.query().with('user').fetch()
- return response.json(cases)
+ let filterBy = request.input('filterBy')
+ if (filterBy == null){
+ let cases = await Case.query().with('versions').fetch()
+ return response.json(cases)
+ }
+ if (filterBy == 'user'){
+ let user = await User.find(request.input('filter'))
+ let cases = await user.cases().fetch()
+ return response.json(cases)
+ }
} catch (e) {
+ console.log(e)
return response.status(e.status).json({ message: e.message })
}
}
@@ -59,89 +44,54 @@ class CaseController {
*/
async show({ params, response }) {
try {
- let c = await Case.find(params.id)
+
+ let c = await Case.find( params.id )
+ let versions = await c.versions().fetch()
+
+ c.source = versions.first().source
+
return response.json(c)
} catch (e) {
return response.status(e.status).json({ message: e.message })
}
}
- async loadCase({ request, response }) {
- try {
- let c = await Case.findBy('caseName', request.input('caseName'))
- return response.json({ 'caseMd': c.caseText })
- } catch (e) {
- return response.status(e.status).json({ message: e.message })
- }
- }
- /**
- * Create/save a new case.
- * POST cases
- *
- * @param {object} ctx
- * @param {Request} ctx.request
- * @param {Response} ctx.response
- */
+ /** * Create/save a new case.*/
async store({ request, auth, response }) {
- try {
- let caseText = request.input('caseText')
- let caseName = request.input('caseName')
-
- fs.access(DIR_CASES, fs.constants.F_OK, (err) => {
- if (err) fs.mkdirSync(DIR_CASES, { recursive: true })
- })
-
- let caseDir = DIR_CASES + caseName + "/"
- let caseFile = caseDir + FILE_CASE;
- let versionsDir = caseDir + "version/"
-
- // copy a version of the previous file
- let versionFile = "new file"
-
- fs.access(caseDir, fs.constants.F_OK, (err) => {
- if (err) fs.mkdirSync(caseDir, { recursive: true })
-
- fs.writeFileSync(caseFile, caseText)
-
- let currentTime = dateFormat(new Date().getTime(), "_yyyy-mm-dd-h-MM-ss_");
- versionFile = FILE_CASE_NAME + currentTime + uuidv1() + FILE_CASE_EXTENSION
- fs.mkdirSync(versionsDir, { recursive: true })
-
- fs.copyFileSync(caseFile, versionsDir + versionFile);
- });
-
- let c = new Case()
- c.caseName = caseName
- c.caseText = JSON.stringify(caseText)
- c.user_id = auth.user.id
- c.url = caseDir
-
- await c.save()
- return response.json({ "versionFile": versionFile })
- } catch (e) {
- return response.status(e.status).json({ message: e.message })
- }
+ console.log('chegou')
+ // try {
+ // let c = new Case()
+ // c.name = request.input('name')
+ // c.user_id = auth.user.id
+
+ // let cv = new CaseVersion()
+ // cv.source = request.input('source')
+
+ // await c.versions().save(cv)
+ // await c.versions().fetch()
+
+ // return response.json(c)
+ // } catch (e) {
+ // console.log(e)
+ // return response.status(e.status).json({ message: e.message })
+ // }
}
- /**
- * Update case details.
- * PUT or PATCH cases/:id
- *
- * @param {object} ctx
- * @param {Request} ctx.request
- * @param {Response} ctx.response
- */
+ /** * Update case details. PUT or PATCH case/:id */
async update({ params, request, response }) {
try {
let c = await Case.find(params.id)
- c.caseName = request.input('caseName')
- console.log(c.caseName)
- c.caseText = request.input('caseText')
+ c.name = request.input('name')
+
+ let cv = new CaseVersion()
+ cv.source = request.input('source')
- await c.save()
+ await c.versions().save(cv)
+ await c.save()
return response.json(c)
} catch (e) {
+ console.log(e)
return response.status(e.status).json({ message: e.message })
}
}
@@ -163,71 +113,18 @@ class CaseController {
}
}
- async newCase({ response }) {
- try {
- let temporaryCase = DIR_CASES + TEMPORARY_CASE
- fse.copySync(DIR_MODELS + BLANK_MODEL, temporaryCase)
- return response.json({ caseName: TEMPORARY_CASE })
- } catch (e) {
- console.log(e)
- }
- }
-
- async renameCase({ params, request, response }) {
+ async newCase({ response, auth }) {
try {
- let oldName = request.input('oldName')
- let newName = request.input('newName')
-
- let c = await Case.findBy('caseName', oldName)
-
- let oldDir = c.url
- let newDir = DIR_CASES + newName
-
- c.caseName = newName
-
- fs.accessSync(oldDir, fs.constants.R_OK | fs.constants.W_OK);
- fs.renameSync(oldDir, newDir)
+ let c = new Case()
+ c.user_id = auth.user.id
await c.save()
- return response.json({ status: 'ok' })
- } catch (e) {
- if (e.code === 'ER_DUP_ENTRY') {
- return response.status(409).json({ status: 'duplicate' })
- }
- return response.status(e.status).json({ message: e.message })
- }
- }
-
- async prepareCaseHTML({ params, request, response }) {
- try {
- let templateFamily = request.input('templateFamily')
- let caseName = request.input('caseName')
-
- fs.accessSync(DIR_CASES + "html", fs.constants.R_OK | fs.constants.W_OK);
- fs.renameSync(oldDir, newDir)
-
- fs.access(DIR_CASES + "html/knots", fs.constants.F_OK, (err) => {
- if (err) fs.mkdirSync(DIR_CASES + "html", { recursive: true })
- });
-
-
- fse.copySync(DIR_PLAYER + FILE_PLAYER, caseDir + "html")
- fse.copySync(DIR_PLAYER + "js", caseDir + "html")
-
- let busFiles = fs.readdirSync(DIR_INFRA+'js');
- busFiles.array.forEach(element => {
- fse.copySync(element, caseDir + "js")
- });
-
- return response.json({ status: 'ok' })
+ return response.json(c)
} catch (e) {
- if (e.code === 'ER_DUP_ENTRY') {
- return response.status(409).json({ status: 'duplicate' })
- }
+ console.log(e)
return response.status(e.status).json({ message: e.message })
}
}
-
}
module.exports = CaseController
diff --git a/src/adonisjs/app/Controllers/Http/v1/UserController.js b/src/adonisjs/app/Controllers/Http/v1/UserController.js
index 250f41d..ca8271f 100644
--- a/src/adonisjs/app/Controllers/Http/v1/UserController.js
+++ b/src/adonisjs/app/Controllers/Http/v1/UserController.js
@@ -4,33 +4,10 @@
/** @typedef {import('@adonisjs/framework/src/Response')} Response */
/** @typedef {import('@adonisjs/framework/src/View')} View */
-const Database = use('Database')
-
const User = use('App/Models/v1/User');
-const Case = use('App/Models/v1/Case');
+const CaseVersion = use('App/Models/v1/CaseVersion');
class UserController {
-
- /**
- * List the cases authored by the user
- * GET users
- *
- * @param {object} ctx
- * @param {Request} ctx.request
- * @param {Response} ctx.response
- * @param {View} ctx.view
- */
- async listCases({ request, response, view }) {
- try{
- let result = await Database.select('title', 'description', 'cases.created_at').from('users').leftJoin('cases', 'users.id', 'cases.user_id')
-
- console.log(result)
- return response.json(result)
- } catch(e){
- console.log(e)
- }
- }
-
/**
* Show a list of all users.
* GET users
@@ -114,34 +91,40 @@ class UserController {
}
}
- /**
- * Delete a user with id.
- * DELETE users/:id
- *
- * @param {object} ctx
- * @param {Request} ctx.request
- * @param {Response} ctx.response
- */
- async destroy({ params, request, response, auth }) {
+ /** Delete a user with id.
+ * DELETE user/:id */
+ async destroy({ params, response, auth }) {
try{
let user = await User.find(params.id)
-
await user.delete()
+
+ return response.json(user)
}catch(e){
return response.status(e.status).json({ message: e.message })
}
}
- async newExecution({ request, auth, response }) {
+ /** List the cases authored by the user */
+ async listCases({ params, response }) {
+ try{
+ let user = await User.find(params.id)
+ let cases = await user.cases().fetch()
+ return response.json(cases)
+ } catch(e){
+ console.log(e)
+ }
+ }
+
+ async newExecution({ request, response }) {
try {
- const {user_id, case_id} = request.post()
+ const {user_id, case_version_id} = request.post()
let user = await User.find(user_id)
- let case1 = await Case.find(case_id)
+ let cv = await CaseVersion.find(case_version_id)
- await user.executions().attach(case1.id)
- user.executions = user.executions().fetch()
-
- response.json(user)
+ await user.executions().attach(cv.id)
+ user.executions = await user.executions().fetch()
+ console.log(user.executions())
+ return response.json(user)
} catch (e) {
console.log(e)
if (e.code === 'ER_DUP_ENTRY') {
diff --git a/src/adonisjs/app/Models/v1/Artifact.js b/src/adonisjs/app/Models/v1/Artifact.js
new file mode 100644
index 0000000..cdbec52
--- /dev/null
+++ b/src/adonisjs/app/Models/v1/Artifact.js
@@ -0,0 +1,9 @@
+'use strict'
+
+/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
+const Model = use('Model')
+
+class Artifact extends Model {
+}
+
+module.exports = Artifact
diff --git a/src/adonisjs/app/Models/v1/Case.js b/src/adonisjs/app/Models/v1/Case.js
index 58da648..bc45840 100644
--- a/src/adonisjs/app/Models/v1/Case.js
+++ b/src/adonisjs/app/Models/v1/Case.js
@@ -8,8 +8,28 @@ class Case extends Model {
return this.belongsTo('App/Models/v1/User');
}
- executions(){
- return this.belongsToMany('App/Models/v1/User').pivotTable('executions')
+ versions(){
+ return this.hasMany('App/Models/v1/CaseVersion')
+ }
+
+ htmlFiles(){
+ return this.hasMany('App/Models/v1/HtmlFile')
+ }
+
+ javascripts(){
+ return this.hasMany('App/Models/v1/JavaScript')
+ }
+
+ cssFiles(){
+ return this.hasMany('App/Models/v1/CSSFile')
+ }
+
+ images(){
+ return this.hasMany('App/Models/v1/Image')
+ }
+
+ dccs(){
+ return this.hasMany('App/Models/v1/Dcc')
}
}
diff --git a/src/adonisjs/app/Models/v1/CaseVersion.js b/src/adonisjs/app/Models/v1/CaseVersion.js
new file mode 100644
index 0000000..aa3212d
--- /dev/null
+++ b/src/adonisjs/app/Models/v1/CaseVersion.js
@@ -0,0 +1,27 @@
+'use strict'
+
+/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
+const Model = use('Model')
+
+const uuidv4 = require('uuid/v4');
+
+class CaseVersion extends Model {
+ case() {
+ return this.belongsTo('App/Models/v1/Case');
+ }
+
+ executions(){
+ return this.belongsToMany('App/Models/v1/User').pivotTable('executions').withTimestamps()
+ }
+
+ static boot() {
+ super.boot()
+
+ /** A hook to hash the user password before saving it to the database.*/
+ this.addHook('beforeSave', async (userInstance) => {
+ userInstance.uuid = await uuidv4()
+ })
+ }
+}
+
+module.exports = CaseVersion
diff --git a/src/adonisjs/app/Models/v1/CssFile.js b/src/adonisjs/app/Models/v1/CssFile.js
new file mode 100644
index 0000000..0a199fb
--- /dev/null
+++ b/src/adonisjs/app/Models/v1/CssFile.js
@@ -0,0 +1,20 @@
+'use strict'
+
+/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
+const Model = use('Model')
+
+class CssFile extends Model {
+ case(){
+ return this.belongsTo('App/Models/v1/Case');
+ }
+
+ style(){
+ return this.belongsTo('App/Models/v1/Style');
+ }
+
+ dcc(){
+ return this.belongsTo('App/Models/v1/Dcc');
+ }
+}
+
+module.exports = CssFile
diff --git a/src/adonisjs/app/Models/v1/Dcc.js b/src/adonisjs/app/Models/v1/Dcc.js
new file mode 100644
index 0000000..13ecf57
--- /dev/null
+++ b/src/adonisjs/app/Models/v1/Dcc.js
@@ -0,0 +1,28 @@
+'use strict'
+
+/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
+const Model = use('Model')
+
+class Dcc extends Model {
+ case(){
+ return this.belongsTo('App/Models/v1/Case');
+ }
+
+ htmlFiles(){
+ return this.hasMany('App/Models/v1/HtmlFile')
+ }
+
+ javascripts(){
+ return this.hasMany('App/Models/v1/JavaScript')
+ }
+
+ cssFiles(){
+ return this.hasMany('App/Models/v1/CssFile')
+ }
+
+ images(){
+ return this.hasMany('App/Models/v1/Image')
+ }
+}
+
+module.exports = Dcc
diff --git a/src/adonisjs/app/Models/v1/Execution.js b/src/adonisjs/app/Models/v1/Execution.js
deleted file mode 100644
index de4bc11..0000000
--- a/src/adonisjs/app/Models/v1/Execution.js
+++ /dev/null
@@ -1,15 +0,0 @@
-'use strict'
-
-/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
-const Model = use('Model')
-
-class Execution extends Model {
- static boot () {
- super.boot()
- this.addHook('beforeCreate', (execution) => {
- execution.is_current_owner = true
- })
- }
-}
-
-module.exports = Execution
diff --git a/src/adonisjs/app/Models/v1/HtmlFile.js b/src/adonisjs/app/Models/v1/HtmlFile.js
new file mode 100644
index 0000000..d411bdc
--- /dev/null
+++ b/src/adonisjs/app/Models/v1/HtmlFile.js
@@ -0,0 +1,20 @@
+'use strict'
+
+/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
+const Model = use('Model')
+
+class HtmlFile extends Model {
+ case() {
+ return this.belongsTo('App/Models/v1/Case');
+ }
+
+ style() {
+ return this.belongsTo('App/Models/v1/Style');
+ }
+
+ dcc(){
+ return this.belongsTo('App/Models/v1/Dcc');
+ }
+}
+
+module.exports = HtmlFile
diff --git a/src/adonisjs/app/Models/v1/Image.js b/src/adonisjs/app/Models/v1/Image.js
new file mode 100644
index 0000000..4410f78
--- /dev/null
+++ b/src/adonisjs/app/Models/v1/Image.js
@@ -0,0 +1,20 @@
+'use strict'
+
+/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
+const Model = use('Model')
+
+class Image extends Model {
+ case(){
+ return this.belongsTo('App/Models/v1/Case');
+ }
+
+ style(){
+ return this.belongsTo('App/Models/v1/Style');
+ }
+
+ dcc(){
+ return this.belongsTo('App/Models/v1/Dcc');
+ }
+}
+
+module.exports = Image
diff --git a/src/adonisjs/app/Models/v1/JavaScript.js b/src/adonisjs/app/Models/v1/JavaScript.js
new file mode 100644
index 0000000..85ab67d
--- /dev/null
+++ b/src/adonisjs/app/Models/v1/JavaScript.js
@@ -0,0 +1,20 @@
+'use strict'
+
+/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
+const Model = use('Model')
+
+class JavaScript extends Model {
+ case(){
+ return this.belongsTo('App/Models/v1/Case');
+ }
+
+ style(){
+ return this.belongsTo('App/Models/v1/Style');
+ }
+
+ dcc(){
+ return this.belongsTo('App/Models/v1/Dcc');
+ }
+}
+
+module.exports = JavaScript
diff --git a/src/adonisjs/app/Models/v1/Style.js b/src/adonisjs/app/Models/v1/Style.js
new file mode 100644
index 0000000..f4b46fc
--- /dev/null
+++ b/src/adonisjs/app/Models/v1/Style.js
@@ -0,0 +1,24 @@
+'use strict'
+
+/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
+const Model = use('Model')
+
+class Style extends Model {
+ htmlFiles(){
+ return this.hasMany('App/Models/v1/HtmlFile')
+ }
+
+ cssFiles(){
+ return this.hasMany('App/Models/v1/CssFile')
+ }
+
+ images(){
+ return this.hasMany('App/Models/v1/Image')
+ }
+
+ javascripts(){
+ return this.hasMany('App/Models/v1/javaScript')
+ }
+}
+
+module.exports = Style
diff --git a/src/adonisjs/app/Models/v1/User.js b/src/adonisjs/app/Models/v1/User.js
index 7d1c470..cd3a0a3 100644
--- a/src/adonisjs/app/Models/v1/User.js
+++ b/src/adonisjs/app/Models/v1/User.js
@@ -5,15 +5,24 @@ const Hash = use('Hash')
/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
const Model = use('Model')
+const Database = use('Database')
+
class User extends Model {
+
+
+ static async getAuthenticatedUser(email){
+ return await Database.table('users').select('username', 'email').where('email', email)
+ }
+
cases() {
return this.hasMany('App/Models/v1/Case')
}
executions () {
return this
- .belongsToMany('App/Models/v1/Case')
+ .belongsToMany('App/Models/v1/CaseVersion')
.pivotTable('executions')
+ .withTimestamps()
}
static boot() {
@@ -43,6 +52,12 @@ class User extends Model {
tokens() {
return this.hasMany('App/Models/Token')
}
+
+ artifacts() {
+ return this.hasMany('App/Models/v1/Artifact')
+ }
+
+
}
module.exports = User
diff --git a/src/adonisjs/config/database.js b/src/adonisjs/config/database.js
index e9cb916..0f40d22 100644
--- a/src/adonisjs/config/database.js
+++ b/src/adonisjs/config/database.js
@@ -17,7 +17,7 @@ module.exports = {
|
*/
connection: Env.get('DB_CONNECTION', 'sqlite'),
-
+ debug: true,
/*
|--------------------------------------------------------------------------
| Sqlite
diff --git a/src/adonisjs/database/factory.js b/src/adonisjs/database/factory.js
index e7fa9f7..0e43375 100644
--- a/src/adonisjs/database/factory.js
+++ b/src/adonisjs/database/factory.js
@@ -12,10 +12,65 @@
*/
/** @type {import('@adonisjs/lucid/src/Factory')} */
-// const Factory = use('Factory')
+const Factory = use('Factory')
+const Hash = use('Hash')
-// Factory.blueprint('App/Models/v1/User', (faker) => {
-// return {
-// username: faker.username()
-// }
-// })
+Factory.blueprint('App/Models/v1/User', async (faker, i, data) => {
+ return {
+ username: faker.username(),
+ email: faker.email(),
+ password: await Hash.make(faker.password())
+ }
+})
+
+Factory.blueprint('App/Models/v1/Case', (faker, i, data) => {
+ return {
+ name: data.name
+ }
+})
+
+Factory.blueprint('App/Models/v1/CaseVersion', async (faker, i, data) => {
+ return {
+ source: data.source
+ }
+})
+
+Factory.blueprint('App/Models/v1/Style', async (faker, i, data) => {
+ return {
+ name: data.name
+ }
+})
+
+Factory.blueprint('App/Models/v1/HtmlFile', async (faker, i, data) => {
+ return {
+ name: data.name,
+ content: data.content,
+ }
+})
+
+Factory.blueprint('App/Models/v1/JavaScript', async (faker, i, data) => {
+ return {
+ name: data.name,
+ content: data.content,
+ }
+})
+
+Factory.blueprint('App/Models/v1/CssFile', async (faker, i, data) => {
+ return {
+ name: data.name,
+ content: data.content,
+ }
+})
+
+Factory.blueprint('App/Models/v1/Image', async (faker, i, data) => {
+ return {
+ name: data.name,
+ url: data.url
+ }
+})
+
+Factory.blueprint('App/Models/v1/Dcc', async (faker, i, data) => {
+ return {
+ name: data.name,
+ }
+})
\ No newline at end of file
diff --git a/src/adonisjs/database/migrations/1554943173614_v_1_case_schema.js b/src/adonisjs/database/migrations/1554943173614_v_1_case_schema.js
index d9022d7..16a3477 100644
--- a/src/adonisjs/database/migrations/1554943173614_v_1_case_schema.js
+++ b/src/adonisjs/database/migrations/1554943173614_v_1_case_schema.js
@@ -7,9 +7,8 @@ class CaseSchema extends Schema {
up () {
this.create('cases', (table) => {
table.increments()
- table.string('caseName').unique()
- table.json('caseText')
- table.string('url')
+ table.string('name').unique()
+
table.integer('user_id').unsigned().references('id').inTable('users');
table.timestamps()
})
diff --git a/src/adonisjs/database/migrations/1555723461998_v_1_case_version_schema.js b/src/adonisjs/database/migrations/1555723461998_v_1_case_version_schema.js
new file mode 100644
index 0000000..869e117
--- /dev/null
+++ b/src/adonisjs/database/migrations/1555723461998_v_1_case_version_schema.js
@@ -0,0 +1,22 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class CaseVersionSchema extends Schema {
+ up () {
+ this.create('case_versions', (table) => {
+ table.increments()
+ table.uuid('uuid')
+ table.text('source')
+ table.integer('case_id').unsigned().references('id').inTable('cases')
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('case_versions')
+ }
+}
+
+module.exports = CaseVersionSchema
diff --git a/src/adonisjs/database/migrations/1555350288168_v_1_execution_schema.js b/src/adonisjs/database/migrations/1555726233031_v_1_execution_schema.js
similarity index 65%
rename from src/adonisjs/database/migrations/1555350288168_v_1_execution_schema.js
rename to src/adonisjs/database/migrations/1555726233031_v_1_execution_schema.js
index 35af752..f2fc2f8 100644
--- a/src/adonisjs/database/migrations/1555350288168_v_1_execution_schema.js
+++ b/src/adonisjs/database/migrations/1555726233031_v_1_execution_schema.js
@@ -6,10 +6,12 @@ const Schema = use('Schema')
class ExecutionSchema extends Schema {
up () {
this.create('executions', (table) => {
+ table.increments()
table.integer('user_id').unsigned().index('user_id')
- table.integer('case_id').unsigned().index('case_id')
+ table.integer('case_version_id').unsigned().index('caseversion_id')
table.foreign('user_id').references('users.id').onDelete('cascade')
- table.foreign('case_id').references('cases.id').onDelete('cascade')
+ table.foreign('case_version_id').references('case_versions.id').onDelete('cascade')
+ table.timestamps()
})
}
diff --git a/src/adonisjs/database/migrations/1555739628715_v_1_style_schema.js b/src/adonisjs/database/migrations/1555739628715_v_1_style_schema.js
new file mode 100644
index 0000000..3e65100
--- /dev/null
+++ b/src/adonisjs/database/migrations/1555739628715_v_1_style_schema.js
@@ -0,0 +1,23 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class StyleSchema extends Schema {
+ up () {
+ this.create('styles', (table) => {
+ table.increments()
+ table.timestamps()
+
+ table.string('name')
+
+
+ })
+ }
+
+ down () {
+ this.drop('styles')
+ }
+}
+
+module.exports = StyleSchema
diff --git a/src/adonisjs/database/migrations/1555758122993_v_1_dcc_schema.js b/src/adonisjs/database/migrations/1555758122993_v_1_dcc_schema.js
new file mode 100644
index 0000000..3b937dd
--- /dev/null
+++ b/src/adonisjs/database/migrations/1555758122993_v_1_dcc_schema.js
@@ -0,0 +1,23 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class DccSchema extends Schema {
+ up () {
+ this.create('dccs', (table) => {
+ table.increments()
+
+ table.string('name')
+ table.integer('case_id').unsigned().references('id').inTable('cases');
+
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('dccs')
+ }
+}
+
+module.exports = DccSchema
diff --git a/src/adonisjs/database/migrations/1555792033731_v_1_java_script_schema.js b/src/adonisjs/database/migrations/1555792033731_v_1_java_script_schema.js
new file mode 100644
index 0000000..f89221b
--- /dev/null
+++ b/src/adonisjs/database/migrations/1555792033731_v_1_java_script_schema.js
@@ -0,0 +1,25 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class JavaScriptSchema extends Schema {
+ up () {
+ this.create('java_scripts', (table) => {
+ table.increments()
+ table.string('name')
+ table.text('content')
+ table.integer('case_id').unsigned().references('id').inTable('cases');
+ table.integer('style_id').unsigned().references('id').inTable('styles');
+
+ table.integer('dcc_id').unsigned().references('id').inTable('dccs');
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('java_scripts')
+ }
+}
+
+module.exports = JavaScriptSchema
diff --git a/src/adonisjs/database/migrations/1555799832791_v_1_html_file_schema.js b/src/adonisjs/database/migrations/1555799832791_v_1_html_file_schema.js
new file mode 100644
index 0000000..3895966
--- /dev/null
+++ b/src/adonisjs/database/migrations/1555799832791_v_1_html_file_schema.js
@@ -0,0 +1,27 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class HtmlFileSchema extends Schema {
+ up () {
+ this.create('html_files', (table) => {
+ table.increments()
+
+ table.string('name')
+ table.text('content')
+
+ table.integer('case_id').unsigned().references('id').inTable('cases')
+ table.integer('style_id').unsigned().references('id').inTable('styles')
+ table.integer('dcc_id').unsigned().references('id').inTable('dccs');
+
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('html_files')
+ }
+}
+
+module.exports = HtmlFileSchema
diff --git a/src/adonisjs/database/migrations/1555876204331_v_1_css_file_schema.js b/src/adonisjs/database/migrations/1555876204331_v_1_css_file_schema.js
new file mode 100644
index 0000000..e42b2c0
--- /dev/null
+++ b/src/adonisjs/database/migrations/1555876204331_v_1_css_file_schema.js
@@ -0,0 +1,26 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class CssFileSchema extends Schema {
+ up () {
+ this.create('css_files', (table) => {
+ table.increments()
+
+ table.string('name')
+ table.text('content')
+ table.integer('case_id').unsigned().references('id').inTable('cases');
+ table.integer('style_id').unsigned().references('id').inTable('styles');
+ table.integer('dcc_id').unsigned().references('id').inTable('dccs');
+
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('css_files')
+ }
+}
+
+module.exports = CssFileSchema
diff --git a/src/adonisjs/database/migrations/1555876234301_v_1_image_schema.js b/src/adonisjs/database/migrations/1555876234301_v_1_image_schema.js
new file mode 100644
index 0000000..0008a3d
--- /dev/null
+++ b/src/adonisjs/database/migrations/1555876234301_v_1_image_schema.js
@@ -0,0 +1,27 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class ImageSchema extends Schema {
+ up () {
+ this.create('images', (table) => {
+ table.increments()
+
+ table.string('name')
+ table.string('url')
+
+ table.integer('case_id').unsigned().references('id').inTable('cases');
+ table.integer('style_id').unsigned().references('id').inTable('styles');
+ table.integer('dcc_id').unsigned().references('id').inTable('dccs');
+
+ table.timestamps()
+ })
+ }
+
+ down () {
+ this.drop('images')
+ }
+}
+
+module.exports = ImageSchema
diff --git a/src/adonisjs/database/migrations/1557089334890_v_1_artifacts_schema.js b/src/adonisjs/database/migrations/1557089334890_v_1_artifacts_schema.js
new file mode 100644
index 0000000..2c51fa5
--- /dev/null
+++ b/src/adonisjs/database/migrations/1557089334890_v_1_artifacts_schema.js
@@ -0,0 +1,26 @@
+'use strict'
+
+/** @type {import('@adonisjs/lucid/src/Schema')} */
+const Schema = use('Schema')
+
+class ArtifactsSchema extends Schema {
+
+ up () {
+
+ this.create('artifacts', (table) => {
+ table.increments()
+ table.integer('user_id').unsigned().references('id').inTable('users');
+ table.integer('case_id').unsigned().references('id').inTable('cases');
+ table.string('fs_path', 300).notNullable()
+ table.string('relative_path', 300).notNullable()
+ table.timestamps()
+ })
+ }
+
+ down () {
+
+ this.drop('artifacts')
+ }
+}
+
+module.exports = ArtifactsSchema
diff --git a/src/adonisjs/database/seeds/DccSeeder.js b/src/adonisjs/database/seeds/DccSeeder.js
new file mode 100644
index 0000000..c0b50be
--- /dev/null
+++ b/src/adonisjs/database/seeds/DccSeeder.js
@@ -0,0 +1,95 @@
+'use strict'
+
+/*
+|--------------------------------------------------------------------------
+| DccSeeder
+|--------------------------------------------------------------------------
+|
+| Make use of the Factory instance to seed database with dummy data or
+| make use of Lucid models directly.
+|
+*/
+
+/** @type {import('@adonisjs/lucid/src/Factory')} */
+const Factory = use('Factory')
+
+const fs = require('fs');
+const path = require("path");
+
+const DCCS_DIR = "../../dccs/"
+
+const RESOURCE_DIR = "resources/"
+const IMAGES_DIR = RESOURCE_DIR + "images/"
+const DCCS_IMAGES_DIR = IMAGES_DIR + "dccs/"
+
+const Dcc = use('App/Models/v1/Dcc');
+
+class DccSeeder {
+ async run () {
+ let dccsName = fs.readdirSync(DCCS_DIR)
+
+ for (let i = 0; i < dccsName.length; i++) {
+ if (dccsName[i] != "README.md"){
+ const DCC_FAMILY_IMAGES_DIR = DCCS_IMAGES_DIR + dccsName[i] +"/"
+
+ try{
+ fs.accessSync(DCCS_IMAGES_DIR, fs.constants.F_OK);
+ } catch(err){
+ fs.mkdirSync(DCCS_IMAGES_DIR)
+ }
+ try{
+ fs.accessSync(DCC_FAMILY_IMAGES_DIR, fs.constants.F_OK);
+ } catch(err){
+ fs.mkdirSync(DCC_FAMILY_IMAGES_DIR)
+ }
+
+ let dcc = await Factory.model('App/Models/v1/Dcc').create({ name: dccsName[i] })
+ // dcc await DCC.find(dcc.id)
+ let DCC_BY_NAME_DIR = DCCS_DIR + dccsName[i] + "/"
+ let files = fs.readdirSync(DCC_BY_NAME_DIR)
+
+ for (let j = 0; j < files.length; j++) {
+ await this.explore(DCC_BY_NAME_DIR+files[j], dcc)
+ }
+ }
+ }
+ }
+
+ async explore(DIR, dcc){
+ if (fs.lstatSync(DIR).isDirectory() ){
+
+ let files = fs.readdirSync(DIR)
+
+ for (let j = 0; j < files.length; j++) {
+ await this.explore(DIR+ '/' + files[j], dcc)
+ }
+ return
+ }
+
+ let file = DIR.split(path.sep).pop()
+
+ let xt = path.extname(DIR).toLowerCase()
+ if (xt === ".html"){
+ let html = await Factory.model('App/Models/v1/HtmlFile').make({ name: file, content: fs.readFileSync(DIR, 'utf8') })
+ await dcc.htmlFiles().save(html)
+ }
+ if (xt === ".js"){
+ let js = await Factory.model('App/Models/v1/JavaScript').make({ name: file, content: fs.readFileSync(DIR, 'utf8') })
+ await dcc.javascripts().save(js)
+ }
+ if (xt === ".css"){
+ let css = await Factory.model('App/Models/v1/CssFile').make({ name: file, content: fs.readFileSync(DIR, 'utf8') })
+ await dcc.cssFiles().save(css)
+ }
+ if (xt === ".svg" || xt === ".png"){
+ let url = DCCS_IMAGES_DIR + path.dirname(DIR).split(path.sep)[3] + "/" + file
+
+ fs.copyFileSync(DIR, url);
+
+ let image = await Factory.model('App/Models/v1/Image').make({ name: file, url: url })
+ await dcc.images().save(image)
+ }
+ }
+}
+
+module.exports = DccSeeder
diff --git a/src/adonisjs/database/seeds/ImageSeeder.js b/src/adonisjs/database/seeds/ImageSeeder.js
new file mode 100644
index 0000000..a1fdf83
--- /dev/null
+++ b/src/adonisjs/database/seeds/ImageSeeder.js
@@ -0,0 +1,46 @@
+'use strict'
+
+/*
+|--------------------------------------------------------------------------
+| ImageSeeder
+|--------------------------------------------------------------------------
+|
+| Make use of the Factory instance to seed database with dummy data or
+| make use of Lucid models directly.
+|
+*/
+
+/** @type {import('@adonisjs/lucid/src/Factory')} */
+const Factory = use('Factory')
+
+const fs = require('fs');
+
+const SHARED_IMAGES_DIR = "../../shared/images/"
+
+const RESOURCE_DIR = "resources/"
+const IMAGES_DIR = RESOURCE_DIR + "images/"
+const IMAGES_SHARED_DIR = IMAGES_DIR + "shared/"
+const PLAYER_DIR = "../../player/"
+const Case = use('App/Models/v1/Case');
+
+class ImageSeeder {
+ async run () {
+
+ let indexFile = fs.readFileSync(PLAYER_DIR + 'index.html', "utf8")
+ let c = await Case.find(1)
+
+ let htmlFile = await Factory.model('App/Models/v1/HtmlFile').make({ name: 'index.html', content: indexFile })
+
+ let jsPlayerFiles = fs.readdirSync(PLAYER_DIR + "js")
+
+ for (let j = 0; j < jsPlayerFiles.length; j++) {
+ let js = await Factory.model('App/Models/v1/JavaScript').make({ name: jsPlayerFiles[j], content: fs.readFileSync(PLAYER_DIR + "js/" + jsPlayerFiles[j], 'utf8') })
+ // console.log(c.javascripts().create(js))
+ Object.assign(c.toJSON(), { tasks: [] })
+ }
+ console.log(c)
+
+ }
+}
+
+module.exports = ImageSeeder
diff --git a/src/adonisjs/database/seeds/StyleSeeder.js b/src/adonisjs/database/seeds/StyleSeeder.js
new file mode 100644
index 0000000..683b22b
--- /dev/null
+++ b/src/adonisjs/database/seeds/StyleSeeder.js
@@ -0,0 +1,84 @@
+'use strict'
+
+/*
+|--------------------------------------------------------------------------
+| StyleSeeder
+|--------------------------------------------------------------------------
+|
+| Make use of the Factory instance to seed database with dummy data or
+| make use of Lucid models directly.
+|
+*/
+
+/** @type {import('@adonisjs/lucid/src/Factory')} */
+const Factory = use('Factory')
+
+const fs = require('fs');
+
+const RESOURCE_DIR = "resources/"
+const TEMPLATE_DIR = RESOURCE_DIR + "templates/"
+
+class StyleSeeder {
+ async run () {
+ let templateNameDirs = fs.readdirSync(TEMPLATE_DIR)
+
+ for (let i = 0; i < templateNameDirs.length; i++) {
+ let style = await Factory.model('App/Models/v1/Style').create({ name: templateNameDirs[i]})
+
+ let templateFamilyDir = TEMPLATE_DIR + templateNameDirs[i] + "/"
+
+ try {
+ let cssDir = templateFamilyDir + "css/"
+ fs.accessSync(cssDir, fs.constants.F_OK);
+
+ let cssFileNames = fs.readdirSync(cssDir)
+
+ for (let j = 0; j < cssFileNames.length; j++) {
+ let css = await Factory.model('App/Models/v1/CssFile').make({ name: cssFileNames[j], content: fs.readFileSync(cssDir + cssFileNames[j], 'utf8') })
+ await style.cssFiles().save(css)
+ }
+ } catch (err) {
+ console.log(err)
+ return;
+ }
+
+ try {
+ const IMAGES_DIR = RESOURCE_DIR + "images/"
+ const TEMPLATES_IMAGES_DIR = IMAGES_DIR + "templates/"
+ const TEMPLATE_FAMILY_IMAGES_DIR = TEMPLATES_IMAGES_DIR + templateNameDirs[i] +"/"
+
+ try{
+ fs.accessSync(IMAGES_DIR, fs.constants.F_OK);
+ } catch(err){
+ fs.mkdirSync(IMAGES_DIR)
+ }
+ try{
+ fs.accessSync(TEMPLATES_IMAGES_DIR, fs.constants.F_OK);
+ } catch(err){
+ fs.mkdirSync(TEMPLATES_IMAGES_DIR)
+ }
+ try{
+ fs.accessSync(TEMPLATE_FAMILY_IMAGES_DIR, fs.constants.F_OK);
+ } catch(err){
+ fs.mkdirSync(TEMPLATE_FAMILY_IMAGES_DIR)
+ }
+
+ let imagesDir = templateFamilyDir + "images/"
+ fs.accessSync(imagesDir, fs.constants.F_OK);
+
+ let imageFileNames = fs.readdirSync(imagesDir)
+
+ for (let j = 0; j < imageFileNames.length; j++) {
+ fs.copyFileSync(imagesDir + imageFileNames[j], TEMPLATE_FAMILY_IMAGES_DIR + imageFileNames[j]);
+ let image = await Factory.model('App/Models/v1/Image').make({ name: imageFileNames[j], url: TEMPLATE_FAMILY_IMAGES_DIR + imageFileNames[j]})
+ await style.images().save(image)
+ }
+ } catch (err) {
+ console.log(err)
+ return;
+ }
+ }
+ }
+}
+
+module.exports = StyleSeeder
diff --git a/src/adonisjs/database/seeds/UserSeeder.js b/src/adonisjs/database/seeds/UserSeeder.js
new file mode 100644
index 0000000..2b05f82
--- /dev/null
+++ b/src/adonisjs/database/seeds/UserSeeder.js
@@ -0,0 +1,41 @@
+'use strict'
+
+/*
+|--------------------------------------------------------------------------
+| UserSeeder
+|--------------------------------------------------------------------------
+|
+| Make use of the Factory instance to seed database with dummy data or
+| make use of Lucid models directly.
+|
+*/
+
+/** @type {import('@adonisjs/lucid/src/Factory')} */
+const Factory = use('Factory')
+
+const User = use('App/Models/v1/User');
+const JavaScript = use('App/Models/v1/JavaScript');
+
+const RESOURCE_DIR = "resources/"
+
+const fs = require('fs');
+const path = require('path');
+
+class UserSeeder {
+ async run() {
+ let user = await User.create({ username: 'jacinto',
+ email: 'jacinto@example.com',
+ password: 'jacinto'})
+
+ const c = await Factory.model('App/Models/v1/Case').make({ name: 'Case1' })
+
+ const cv = await Factory.model('App/Models/v1/CaseVersion').make({ source: fs.readFileSync(RESOURCE_DIR + 'case.md', 'utf8') })
+
+ await c.versions().save(cv)
+ await user.cases().save(c)
+
+ await Factory.model('App/Models/v1/User').createMany(5)
+ }
+}
+
+module.exports = UserSeeder
diff --git a/src/adonisjs/public/logo.svg b/src/adonisjs/public/logo.svg
deleted file mode 100644
index c8be274..0000000
--- a/src/adonisjs/public/logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/adonisjs/public/pyramid.png b/src/adonisjs/public/pyramid.png
deleted file mode 100644
index 369ab18..0000000
Binary files a/src/adonisjs/public/pyramid.png and /dev/null differ
diff --git a/src/adonisjs/public/splash.png b/src/adonisjs/public/splash.png
deleted file mode 100644
index 7ea4fe0..0000000
Binary files a/src/adonisjs/public/splash.png and /dev/null differ
diff --git a/src/adonisjs/public/style.css b/src/adonisjs/public/style.css
deleted file mode 100644
index c805815..0000000
--- a/src/adonisjs/public/style.css
+++ /dev/null
@@ -1,92 +0,0 @@
-@import url('https://fonts.googleapis.com/css?family=Montserrat:300');
-
-html, body {
- height: 100%;
- width: 100%;
-}
-
-body {
- font-family: 'Montserrat', sans-serif;
- font-weight: 300;
- background-image: url("/splash.png");
- background-color: #220052;
-}
-
-* {
- margin: 0;
- padding: 0;
-}
-
-section {
- height: 100%;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- max-width: 536px;
- margin: auto;
- position: relative;
-}
-
-section:before {
- content: "";
- position: absolute;
- background: url("/pyramid.png") no-repeat;
- background-size: 100%;
- width: 100%;
- height: 402px;
- z-index: -1;
-}
-
-.logo {
- background: url("/logo.svg") no-repeat;
- width: 36px;
- height: 33px;
- background-size: 100%;
- margin-bottom: 35px;
- opacity: 0;
- animation: slideUp 1s cubic-bezier(0.19, 1, 0.30, 1) 1.3s forwards;
-}
-
-.title {
- background: url("/title.svg") no-repeat;
- width: 219px;
- height: 36px;
- background-size: 100%;
- opacity: 0;
- animation: slideUp 1s cubic-bezier(0.19, 1, 0.30, 1) 0.2s forwards;
-}
-
-.subtitle {
- margin-top: 25px;
- color: #BDB3CB;
- font-size: 17px;
- text-align: center;
- letter-spacing: 0.5;
- opacity: 0;
- animation: slideUp 1s cubic-bezier(0.19, 1, 0.30, 1) 0.5s forwards;
-}
-
-
-a {
- color: inherit;
- text-decoration: underline;
-}
-
-p {
- margin: 0.83rem 0;
-}
-
-@keyframes slideUp {
- 0% {
- transform: translateY(40px);
- opacity: 0;
- }
- 50% {
- opacity: 0.2%;
- }
- 100% {
- opacity: 1;
- transform: none;
- }
-}
diff --git a/src/adonisjs/public/title.svg b/src/adonisjs/public/title.svg
deleted file mode 100644
index 38dea69..0000000
--- a/src/adonisjs/public/title.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/adonisjs/resources/case.md b/src/adonisjs/resources/case.md
new file mode 100644
index 0000000..083fc16
--- /dev/null
+++ b/src/adonisjs/resources/case.md
@@ -0,0 +1,675 @@
+Start
+=====
+
+## Case 001 (start,dialog_left)
+:NURSE Agnes: Doctor, we have a man (51 years old) who entered the emergency department reporting chest pain. His vital signs are ABP: 144x92mmHG; HR: 78bpm; RR: 21rpm; Temp: 37oC; O2Sat: 98%.
+
+* Let us go! -> Cycle 1.Begin
+
+Cycle 1
+=======
+
+Begin (information)
+-------------------
+
+:PATIENT Jakob: Doctor, I am feeling chest pain since yesterday. The pain is continuous and is located just in the middle of my chest, worsening when I breathe and when I lay down on my bed. I suffer from arterial hypertension and smoke 20 cigarettes every day. My father had a “heart attack” at my age and I am very worried about it.
+
+PHYSICAL EXAMINATION
The cardiac and pulmonary auscultation are normal; chest pain does not worse with palpation of the thorax; there is no jugular stasis nor lower limb edema.
+
+:Jacinto:What do you want to do?
+
+* -> Generate hypothesis
+* -> More information
+* Call the supervisor -> Call the supervisor.A
+
+Generate hypothesis (input)
+---------------------------
+What is your main diagnostic hypothesis?
+:PATIENT Jakob:.
+{?1 hypothesis:mesh#pericarditis,myopericarditis,pericardial inflammation,pericardial infection,pericardial effusion;infarction,myocardial infarction,coronary syndrome,acute coronary syndrome,ischemia,myocardial ischemia,coronary insufficiency,angina,angina pectoris}
+
+* Submit hypothesis -> Check hypothesis
+
+More information (information)
+------------------------------
+
+MORE INFORMATION
The patient never felt chest pain before. He exercises regularly and has lost weight in the last three months. He takes amlodipine and losartan regularly. Two weeks ago, he had an auto-limited gastroenteritis episode. He denies recent travels and surgery.
+:PATIENT Jakob:.
+
+:Jacinto:What do you want to do?
+
+* Generate hypothesis -> Generate hypothesis
+* Call the supervisor -> Call the supervisor.A
+
+Call the supervisor
+-------------------
+
+### A (detailed)
+:SUPERVISOR Harry:
+Hi! I am glad that you called me. Chest pain is an important complaint at the emergency department and we have to exclude the fatal causes: myocardial infarction (MI), acute aortic dissection (AAD), pulmonary embolism PE), hypertensive pneumothorax (HP), and Boerhaave Syndrome (BS).
+
+The best way to find out what is happening with your patient, my young padawan, is to gather as much information as possible through history taking and physical examination. We need to search for the signs and symptoms that can guide our clinical reasoning process by changing the pre-test probabilities of each disease.
+::
+
+* See likelihood tables -> B
+
+### B (detailed)
+:SUPERVISOR Harry:.
+**Likelihood Tables**
+
+Do you know the concept of Likelihood ratio (LR)? -> Likelihood Ratio
+
++ -> Clinical History Myocardial Infarction
+
++ -> Physical Examination Myocardial Infarction
+
++ -> Clinical History Aortic Dissection
+
++ -> Physical Examination Aortic Dissection
+
++ -> Pulmonary Embolism Wells Criteria
+
+* Continue talking -> C
+
+### C (detailed)
+:SUPERVISOR Harry:.
+Hypertensive pneumothorax is more common in tall and thin young adults (primary pneumothorax) or in patients with chronic pulmonary diseases or chest trauma (secondary pneumothorax). On physical examination, we expect asymmetry in lung auscultation and the trachea may be dislocated to the contralateral side of the pneumothorax.
+
+Boerhaave Syndrome is more common in patients who presented vomiting before the chest pain started, were submitted to endoscopic procedures or had chest trauma.
+
+How does this information can help you to solve your case?
+
+* Back to the case -> Cycle 1.Begin
+
+### Likelihood Ratio (note)
+
+Likelihood ratio (LR) - like sensitivity and specificity, LR describe the discriminatory power of features in a clinical context, estimating the probability of disease. When the LR is higher than 1, the feature increases the probability; when lower than 1, reduces it.
+
+* Back -> Supervisor B
+
+### Clinical History Myocardial Infarction (note)
+![Clinical History Myocardial Infarction](images/ebm-clinical-history-myocardial-infarction.png)
+
+* Back -> Supervisor B
+
+### Physical Examination Myocardial Infarction (note)
+![Physical Examination Myocardial Infarction](images/ebm-physical-examination-myocardial-infarction.png)
+
+* Back -> Supervisor B
+
+### Clinical History Aortic Dissection (note)
+![Clinical History Aortic Dissection](images/ebm-clinical-history-aortic-dissection.png)
+
+* Back -> Supervisor B
+
+### Physical Examination Aortic Dissection (note)
+![Physical Examination Aortic Dissection](images/ebm-physical-examination-aortic-dissection.png)
+
+* Back -> Call the supervisor B
+
+### Pulmonary Embolism Wells Criteria (note)
+![Pulmonary Embolism Wells Criteria](images/ebm-pulmonary-embolism-wells-criteria.png)
+
+* Back -> Call the supervisor B
+
+Check hypothesis (selector)
+---------------------------
+
+:Jacinto:Let us check out your hypothesis. Highlight in green the findings that corroborate your hypothesis; in blue those that are neutral; and in red the ones speaking against your hypothesis.
+
+{{symptoms#contribution to diagnostics: ,+,=,-
+Nurse: Doctor, please you have to evaluate a {man(male)} ({51 years-old(aging=51)#=}) who entered the emergency department reporting {chest pain#=}.His vital signs are {ABP: 144x92mmHG#=}; {HR: 78bpm#=}; {RR: 21rpm#=}; {Temp: 37oC#=}; {O2Sat: 98%#=}.
+
+Patient: Doctor, I am feeling chest pain since yesterday. The {pain is continuous#=} and {is located just in the middle of my chest#=}, {worsening when I breathe#+} and {when I lay down on my bed#+}. I have {arterial hypertension#-} and {I smoke 20 cigarettes(smoking=20/day)#-} every day. {My father had a "heart attack"#-} at my age and I am very worried about it.
+
+You perform physical examination: {cardiac and pulmonary auscultation are normal#-}; {chest pain does not worse with palpation of the thorax#=}; {there is no jugular stasis#=} {nor lower limb edema#=}.
+}}
+
+* Submit -> Review hypothesis
+
+Review hypothesis (input)
+-------------------------
+If you whant to review your hypothesis, type below the new hypothesis.
+:PATIENT Jakob:.
+{?1 hypothesis:mesh#pericarditis,myopericarditis,pericardial inflammation,pericardial infection,pericardial effusion;infarction,myocardial infarction,coronary syndrome,acute coronary syndrome,ischemia,myocardial ischemia,coronary insufficiency,angina,angina pectoris}
+
+* Submit -> Cycle 2.Order EKG
+
+Cycle 2
+=======
+
+## Order EKG (decision_exam)
+Our patient denies any recent long trip, immobilization or surgery.
+
+The blood pressure is symmetric in the four limbs.
+
+:EKG:.
+
+* Magnify -> Magnify EKG
+
+:Game: What do you want to do?
+* -> Generate hypothesis
+* -> More information
+* -> Call the supervisor
+
+
+## Magnify EKG (note,magnify_exam)
+
+:EKG:.
+
+* Return -> Order EKG
+
+## Generate hypothesis (input)
+What is your main diagnostic hypothesis?
+:PATIENT Jakob:.
+{?1 hypothesis:mesh#pericarditis,myopericarditis,pericardial inflammation,pericardial infection,pericardial effusion;infarction,myocardial infarction,coronary syndrome,acute coronary syndrome,ischemia,myocardial ischemia,coronary insufficiency,angina,angina pectoris}
+
+* Submit hypothesis -> Check hypothesis
+
+## More information (decision_exam)
+
+![EKG Description](images/ekg-description.png)
+
+* EKG Analysis
+
+:EKG:.
+
+:Game: What do you want to do?
+* Back -> Order EKG
+* Analyze EKG -> EKG Analysis
+
+## EKG Analysis (note,marker_exam)
+
+
+
+
+
+
+
+
+
+
+
+* Return -> Order EKG
+
+## Call the supervisor (decision_exam)
+
+We did not find features that increase the likelihood of myocardial ischemia. Moreover, our patient has a pleuritic chest pain that gets worse when the patient lays down.
+
+In the EKG we found ST-segment elevation in almost all leads. Also, we found a depression of the PR segment in the DII lead.
+
+* -> EKG Analysis
+
+:EKG:.
+
+:Game: What do you want to do?
+* Back -> Order EKG
+* Analyze EKG -> EKG Analysis
+
+## Check hypothesis (marker_exam)
+
+
+
+
+
+
+
+
+
+
+
+* Submit -> Review hypothesis
+
+## Review hypothesis (input)
+If you whant to review your hypothesis, type below the new hypothesis.
+:PATIENT Jakob:.
+{?1 hypothesis:mesh#pericarditis,myopericarditis,pericardial inflammation,pericardial infection,pericardial effusion;infarction,myocardial infarction,coronary syndrome,acute coronary syndrome,ischemia,myocardial ischemia,coronary insufficiency,angina,angina pectoris}
+
+* Submit -> Final.Report
+
+Final
+=====
+
+Report (detailed)
+-----------------
+
+Congratulations, my young Dr. you could helped your patient providing his diagnosis. Now, Let's review all levels of this case.
+
+:Computer:Select a final report level:
+
+* -> Level 1
+* -> Level 2.2a
+* -> Level 3.3a
+
+Level 1 (detailed)
+------------------
+
+Level 1: your answer was .
+
+Our patient complained about chest pain, located in the middle of his chest, worsening when he breaths and when he lay down on his bed. Both features increases the probability of pericardial disease, especially acute pericarditis. Although patient´s father died of a "heart attack", there were no chest pain features that increase the probability of myocardial infarction, as the pain did not irradiate to arms, the pain was not described as a pressure, neither complaining about nausea, vomiting or shortness of breath. Another differential diagnosis to consider is myopericarditis, but we not be able to find heart failure signs (pulmonary and cardiac auscultation were normal) and the patient did not complain about dyspnea. So, at the level 1, the answer to our open-ended question was Acute Pericarditis.
+
+* Next -> Level 2.2a
+* Return -> Report
+
+Level 2
+-------
+
+### 2a (detailed)
+
+
+Level 2: At this level, we asked you to highlight in green all features that corroborate your hypothesis, in blue those are neutral and in red the ones speaking against your hypothesis.
+
+Your answer:
+
+{{player#Cycle_1.Check_hypothesis.symptoms: ,+,=,-
+Nurse: Doctor, please you have to evaluate a {man(male)} ({51 years-old(aging=51)#=}) who entered the emergency department reporting {chest pain#=}.His vital signs are {ABP: 144x92mmHG#=}; {HR: 78bpm#=}; {RR: 21rpm#=}; {Temp: 37oC#=}; {O2Sat: 98%#=}.
+
+Patient: Doctor, I am feeling chest pain since yesterday. The {pain is continuous#=} and {is located just in the middle of my chest#=}, {worsening when I breathe#+} and {when I lay down on my bed#+}. I have {arterial hypertension#-} and {I smoke 20 cigarettes(smoking=20/day)#-} every day. {My father had a "heart attack"#-} at my age and I am very worried about it.
+
+You perform physical examination: {cardiac and pulmonary auscultation are normal#-}; {chest pain does not worse with palpation of the thorax#=}; {there is no jugular stasis#=} {nor lower limb edema#=}.
+}}
+
+Our answer:
+
+{{answers#answers: ,+,=,-
+Nurse: Doctor, please you have to evaluate a {man(male)} ({51 years-old(aging=51)#=}) who entered the emergency department reporting {chest pain#=}.His vital signs are {ABP: 144x92mmHG#=}; {HR: 78bpm#=}; {RR: 21rpm#=}; {Temp: 37oC#=}; {O2Sat: 98%#=}.
+
+Patient: Doctor, I am feeling chest pain since yesterday. The {pain is continuous#=} and {is located just in the middle of my chest#=}, {worsening when I breathe#+} and {when I lay down on my bed#+}. I have {arterial hypertension#-} and {I smoke 20 cigarettes(smoking=20/day)#-} every day. {My father had a "heart attack"#-} at my age and I am very worried about it.
+
+You perform physical examination: {cardiac and pulmonary auscultation are normal#-}; {chest pain does not worse with palpation of the thorax#=}; {there is no jugular stasis#=} {nor lower limb edema#=}.
+}}
+
+
+* Next -> 2b
+* Return -> Final.Report
+
+### 2b (detailed)
+
+After checking the hypothesis you reviewed your answer to: .
+
+In acute pericarditis, patients are usually young, most cases are reported under 50 years old, but it can be diagnosed at any age. There is no vital signs features that increase the probability of this condition. Some patients may present fever and tachycardia, but it´s not common signs. So, when vital signs are normal, we cannot confirm or exclude this diagnosis.
+
+In clinical history, two features increase the probability of the chest pain being related to a pericardial disease: worsening with breathing; and worsening when the patient lay down.
+
+* Next -> 2c
+* Return -> Final.Report
+
+### 2c (detailed)
+
+As the patient has arterial hypertension, is smoker and his father died of a "heart attack" we could consider myocardial infarction as one of the diagnosis. But considering chest pain features of our patient, there is no one that increases this possibility. So, these features may lead us to cognitive error if we consider myocardial infarction as the main diagnosis (which is wrong).
+
+In physical examination in patients with acute pericarditis, we may find pericardial rub, one of the diagnostic criteria. So, when we did not find it, the probability of the disease is reduced, but did not exclude the diagnosis. It is crucial to look for the other diagnostic criteria.
+
+* Next -> Level 3.3a
+* Return -> Final.Report
+
+Level 3
+-------
+
+### 3a (detailed)
+
+My young Dr, the EKG interpretation was very helpful to solve our case.
+
+We found a diffuse ST-segment elevation, and a PR-segment depression in DII lead. These findings, associated to the clinical scenario, strongly indicate the main hypothesis of Acute Pericarditis.
+
+* Next -> 3b
+* Return -> Final.Report
+
+### 3b (detailed)
+
+My young Dr, the EKG interpretation was very helpful to solve our case.
+
+We found a diffuse ST-segment elevation, and a PR-segment depression in DII lead. These findings, associated to the clinical scenario, strongly indicate the main hypothesis of Acute Pericarditis.
+
+* Next -> 3c
+* Return -> Final.Report
+
+### 3c (detailed)
+
+In the following table, we provide the diagnostic criteria for acute pericaditis and myopericarditis:
+
+![Clinical History Myocardial Infarction](images/ebm-pericarditis.png)
+
+Cooper LT, Imazio M. Management of myopericarditis. Expert Rev Cardiovasc Ther 2013; 11(2): 193-201.
+
+Our patient fullfill the following criteria: 1 and 3. So, acute pericarditis is the main diagnostic hypothesis.
+
+
+* Return -> Final.Report Start
+=====
+
+## Case 001 (start,dialog_left)
+:NURSE Agnes: Doctor, we have a man (51 years old) who entered the emergency department reporting chest pain. His vital signs are ABP: 144x92mmHG; HR: 78bpm; RR: 21rpm; Temp: 37oC; O2Sat: 98%.
+
+* Let us go! -> Cycle 1.Begin
+
+Cycle 1
+=======
+
+Begin (information)
+-------------------
+
+:PATIENT Jakob: Doctor, I am feeling chest pain since yesterday. The pain is continuous and is located just in the middle of my chest, worsening when I breathe and when I lay down on my bed. I suffer from arterial hypertension and smoke 20 cigarettes every day. My father had a “heart attack” at my age and I am very worried about it.
+
+PHYSICAL EXAMINATION
The cardiac and pulmonary auscultation are normal; chest pain does not worse with palpation of the thorax; there is no jugular stasis nor lower limb edema.
+
+:Jacinto:What do you want to do?
+
+* -> Generate hypothesis
+* -> More information
+* Call the supervisor -> Call the supervisor.A
+
+Generate hypothesis (input)
+---------------------------
+What is your main diagnostic hypothesis?
+:PATIENT Jakob:.
+{?1 hypothesis:mesh#pericarditis,myopericarditis,pericardial inflammation,pericardial infection,pericardial effusion;infarction,myocardial infarction,coronary syndrome,acute coronary syndrome,ischemia,myocardial ischemia,coronary insufficiency,angina,angina pectoris}
+
+* Submit hypothesis -> Check hypothesis
+
+More information (information)
+------------------------------
+
+MORE INFORMATION
The patient never felt chest pain before. He exercises regularly and has lost weight in the last three months. He takes amlodipine and losartan regularly. Two weeks ago, he had an auto-limited gastroenteritis episode. He denies recent travels and surgery.
+:PATIENT Jakob:.
+
+:Jacinto:What do you want to do?
+
+* Generate hypothesis -> Generate hypothesis
+* Call the supervisor -> Call the supervisor.A
+
+Call the supervisor
+-------------------
+
+### A (detailed)
+:SUPERVISOR Harry:
+Hi! I am glad that you called me. Chest pain is an important complaint at the emergency department and we have to exclude the fatal causes: myocardial infarction (MI), acute aortic dissection (AAD), pulmonary embolism PE), hypertensive pneumothorax (HP), and Boerhaave Syndrome (BS).
+
+The best way to find out what is happening with your patient, my young padawan, is to gather as much information as possible through history taking and physical examination. We need to search for the signs and symptoms that can guide our clinical reasoning process by changing the pre-test probabilities of each disease.
+::
+
+* See likelihood tables -> B
+
+### B (detailed)
+:SUPERVISOR Harry:.
+**Likelihood Tables**
+
+Do you know the concept of Likelihood ratio (LR)? -> Likelihood Ratio
+
++ -> Clinical History Myocardial Infarction
+
++ -> Physical Examination Myocardial Infarction
+
++ -> Clinical History Aortic Dissection
+
++ -> Physical Examination Aortic Dissection
+
++ -> Pulmonary Embolism Wells Criteria
+
+* Continue talking -> C
+
+### C (detailed)
+:SUPERVISOR Harry:.
+Hypertensive pneumothorax is more common in tall and thin young adults (primary pneumothorax) or in patients with chronic pulmonary diseases or chest trauma (secondary pneumothorax). On physical examination, we expect asymmetry in lung auscultation and the trachea may be dislocated to the contralateral side of the pneumothorax.
+
+Boerhaave Syndrome is more common in patients who presented vomiting before the chest pain started, were submitted to endoscopic procedures or had chest trauma.
+
+How does this information can help you to solve your case?
+
+* Back to the case -> Cycle 1.Begin
+
+### Likelihood Ratio (note)
+
+Likelihood ratio (LR) - like sensitivity and specificity, LR describe the discriminatory power of features in a clinical context, estimating the probability of disease. When the LR is higher than 1, the feature increases the probability; when lower than 1, reduces it.
+
+* Back -> Supervisor B
+
+### Clinical History Myocardial Infarction (note)
+![Clinical History Myocardial Infarction](images/ebm-clinical-history-myocardial-infarction.png)
+
+* Back -> Supervisor B
+
+### Physical Examination Myocardial Infarction (note)
+![Physical Examination Myocardial Infarction](images/ebm-physical-examination-myocardial-infarction.png)
+
+* Back -> Supervisor B
+
+### Clinical History Aortic Dissection (note)
+![Clinical History Aortic Dissection](images/ebm-clinical-history-aortic-dissection.png)
+
+* Back -> Supervisor B
+
+### Physical Examination Aortic Dissection (note)
+![Physical Examination Aortic Dissection](images/ebm-physical-examination-aortic-dissection.png)
+
+* Back -> Call the supervisor B
+
+### Pulmonary Embolism Wells Criteria (note)
+![Pulmonary Embolism Wells Criteria](images/ebm-pulmonary-embolism-wells-criteria.png)
+
+* Back -> Call the supervisor B
+
+Check hypothesis (selector)
+---------------------------
+
+:Jacinto:Let us check out your hypothesis. Highlight in green the findings that corroborate your hypothesis; in blue those that are neutral; and in red the ones speaking against your hypothesis.
+
+{{symptoms#contribution to diagnostics: ,+,=,-
+Nurse: Doctor, please you have to evaluate a {man(male)} ({51 years-old(aging=51)#=}) who entered the emergency department reporting {chest pain#=}.His vital signs are {ABP: 144x92mmHG#=}; {HR: 78bpm#=}; {RR: 21rpm#=}; {Temp: 37oC#=}; {O2Sat: 98%#=}.
+
+Patient: Doctor, I am feeling chest pain since yesterday. The {pain is continuous#=} and {is located just in the middle of my chest#=}, {worsening when I breathe#+} and {when I lay down on my bed#+}. I have {arterial hypertension#-} and {I smoke 20 cigarettes(smoking=20/day)#-} every day. {My father had a "heart attack"#-} at my age and I am very worried about it.
+
+You perform physical examination: {cardiac and pulmonary auscultation are normal#-}; {chest pain does not worse with palpation of the thorax#=}; {there is no jugular stasis#=} {nor lower limb edema#=}.
+}}
+
+* Submit -> Review hypothesis
+
+Review hypothesis (input)
+-------------------------
+If you whant to review your hypothesis, type below the new hypothesis.
+:PATIENT Jakob:.
+{?1 hypothesis:mesh#pericarditis,myopericarditis,pericardial inflammation,pericardial infection,pericardial effusion;infarction,myocardial infarction,coronary syndrome,acute coronary syndrome,ischemia,myocardial ischemia,coronary insufficiency,angina,angina pectoris}
+
+* Submit -> Cycle 2.Order EKG
+
+Cycle 2
+=======
+
+## Order EKG (decision_exam)
+Our patient denies any recent long trip, immobilization or surgery.
+
+The blood pressure is symmetric in the four limbs.
+
+:EKG:.
+
+* Magnify -> Magnify EKG
+
+:Game: What do you want to do?
+* -> Generate hypothesis
+* -> More information
+* -> Call the supervisor
+
+
+## Magnify EKG (note,magnify_exam)
+
+:EKG:.
+
+* Return -> Order EKG
+
+## Generate hypothesis (input)
+What is your main diagnostic hypothesis?
+:PATIENT Jakob:.
+{?1 hypothesis:mesh#pericarditis,myopericarditis,pericardial inflammation,pericardial infection,pericardial effusion;infarction,myocardial infarction,coronary syndrome,acute coronary syndrome,ischemia,myocardial ischemia,coronary insufficiency,angina,angina pectoris}
+
+* Submit hypothesis -> Check hypothesis
+
+## More information (decision_exam)
+
+![EKG Description](images/ekg-description.png)
+
+* EKG Analysis
+
+:EKG:.
+
+:Game: What do you want to do?
+* Back -> Order EKG
+* Analyze EKG -> EKG Analysis
+
+## EKG Analysis (note,marker_exam)
+
+
+
+
+
+
+
+
+
+
+
+* Return -> Order EKG
+
+## Call the supervisor (decision_exam)
+
+We did not find features that increase the likelihood of myocardial ischemia. Moreover, our patient has a pleuritic chest pain that gets worse when the patient lays down.
+
+In the EKG we found ST-segment elevation in almost all leads. Also, we found a depression of the PR segment in the DII lead.
+
+* -> EKG Analysis
+
+:EKG:.
+
+:Game: What do you want to do?
+* Back -> Order EKG
+* Analyze EKG -> EKG Analysis
+
+## Check hypothesis (marker_exam)
+
+
+
+
+
+
+
+
+
+
+
+* Submit -> Review hypothesis
+
+## Review hypothesis (input)
+If you whant to review your hypothesis, type below the new hypothesis.
+:PATIENT Jakob:.
+{?1 hypothesis:mesh#pericarditis,myopericarditis,pericardial inflammation,pericardial infection,pericardial effusion;infarction,myocardial infarction,coronary syndrome,acute coronary syndrome,ischemia,myocardial ischemia,coronary insufficiency,angina,angina pectoris}
+
+* Submit -> Final.Report
+
+Final
+=====
+
+Report (detailed)
+-----------------
+
+Congratulations, my young Dr. you could helped your patient providing his diagnosis. Now, Let's review all levels of this case.
+
+:Computer:Select a final report level:
+
+* -> Level 1
+* -> Level 2.2a
+* -> Level 3.3a
+
+Level 1 (detailed)
+------------------
+
+Level 1: your answer was .
+
+Our patient complained about chest pain, located in the middle of his chest, worsening when he breaths and when he lay down on his bed. Both features increases the probability of pericardial disease, especially acute pericarditis. Although patient´s father died of a "heart attack", there were no chest pain features that increase the probability of myocardial infarction, as the pain did not irradiate to arms, the pain was not described as a pressure, neither complaining about nausea, vomiting or shortness of breath. Another differential diagnosis to consider is myopericarditis, but we not be able to find heart failure signs (pulmonary and cardiac auscultation were normal) and the patient did not complain about dyspnea. So, at the level 1, the answer to our open-ended question was Acute Pericarditis.
+
+* Next -> Level 2.2a
+* Return -> Report
+
+Level 2
+-------
+
+### 2a (detailed)
+
+
+Level 2: At this level, we asked you to highlight in green all features that corroborate your hypothesis, in blue those are neutral and in red the ones speaking against your hypothesis.
+
+Your answer:
+
+{{player#Cycle_1.Check_hypothesis.symptoms: ,+,=,-
+Nurse: Doctor, please you have to evaluate a {man(male)} ({51 years-old(aging=51)#=}) who entered the emergency department reporting {chest pain#=}.His vital signs are {ABP: 144x92mmHG#=}; {HR: 78bpm#=}; {RR: 21rpm#=}; {Temp: 37oC#=}; {O2Sat: 98%#=}.
+
+Patient: Doctor, I am feeling chest pain since yesterday. The {pain is continuous#=} and {is located just in the middle of my chest#=}, {worsening when I breathe#+} and {when I lay down on my bed#+}. I have {arterial hypertension#-} and {I smoke 20 cigarettes(smoking=20/day)#-} every day. {My father had a "heart attack"#-} at my age and I am very worried about it.
+
+You perform physical examination: {cardiac and pulmonary auscultation are normal#-}; {chest pain does not worse with palpation of the thorax#=}; {there is no jugular stasis#=} {nor lower limb edema#=}.
+}}
+
+Our answer:
+
+{{answers#answers: ,+,=,-
+Nurse: Doctor, please you have to evaluate a {man(male)} ({51 years-old(aging=51)#=}) who entered the emergency department reporting {chest pain#=}.His vital signs are {ABP: 144x92mmHG#=}; {HR: 78bpm#=}; {RR: 21rpm#=}; {Temp: 37oC#=}; {O2Sat: 98%#=}.
+
+Patient: Doctor, I am feeling chest pain since yesterday. The {pain is continuous#=} and {is located just in the middle of my chest#=}, {worsening when I breathe#+} and {when I lay down on my bed#+}. I have {arterial hypertension#-} and {I smoke 20 cigarettes(smoking=20/day)#-} every day. {My father had a "heart attack"#-} at my age and I am very worried about it.
+
+You perform physical examination: {cardiac and pulmonary auscultation are normal#-}; {chest pain does not worse with palpation of the thorax#=}; {there is no jugular stasis#=} {nor lower limb edema#=}.
+}}
+
+
+* Next -> 2b
+* Return -> Final.Report
+
+### 2b (detailed)
+
+After checking the hypothesis you reviewed your answer to: .
+
+In acute pericarditis, patients are usually young, most cases are reported under 50 years old, but it can be diagnosed at any age. There is no vital signs features that increase the probability of this condition. Some patients may present fever and tachycardia, but it´s not common signs. So, when vital signs are normal, we cannot confirm or exclude this diagnosis.
+
+In clinical history, two features increase the probability of the chest pain being related to a pericardial disease: worsening with breathing; and worsening when the patient lay down.
+
+* Next -> 2c
+* Return -> Final.Report
+
+### 2c (detailed)
+
+As the patient has arterial hypertension, is smoker and his father died of a "heart attack" we could consider myocardial infarction as one of the diagnosis. But considering chest pain features of our patient, there is no one that increases this possibility. So, these features may lead us to cognitive error if we consider myocardial infarction as the main diagnosis (which is wrong).
+
+In physical examination in patients with acute pericarditis, we may find pericardial rub, one of the diagnostic criteria. So, when we did not find it, the probability of the disease is reduced, but did not exclude the diagnosis. It is crucial to look for the other diagnostic criteria.
+
+* Next -> Level 3.3a
+* Return -> Final.Report
+
+Level 3
+-------
+
+### 3a (detailed)
+
+My young Dr, the EKG interpretation was very helpful to solve our case.
+
+We found a diffuse ST-segment elevation, and a PR-segment depression in DII lead. These findings, associated to the clinical scenario, strongly indicate the main hypothesis of Acute Pericarditis.
+
+* Next -> 3b
+* Return -> Final.Report
+
+### 3b (detailed)
+
+My young Dr, the EKG interpretation was very helpful to solve our case.
+
+We found a diffuse ST-segment elevation, and a PR-segment depression in DII lead. These findings, associated to the clinical scenario, strongly indicate the main hypothesis of Acute Pericarditis.
+
+* Next -> 3c
+* Return -> Final.Report
+
+### 3c (detailed)
+
+In the following table, we provide the diagnostic criteria for acute pericaditis and myopericarditis:
+
+![Clinical History Myocardial Infarction](images/ebm-pericarditis.png)
+
+Cooper LT, Imazio M. Management of myopericarditis. Expert Rev Cardiovasc Ther 2013; 11(2): 193-201.
+
+Our patient fullfill the following criteria: 1 and 3. So, acute pericarditis is the main diagnostic hypothesis.
+
+
+* Return -> Final.Report
\ No newline at end of file
diff --git a/src/adonisjs/resources/cases/Case1/images/entrance.jpg b/src/adonisjs/resources/cases/Case1/images/entrance.jpg
new file mode 100644
index 0000000..1dd4be7
Binary files /dev/null and b/src/adonisjs/resources/cases/Case1/images/entrance.jpg differ
diff --git a/src/adonisjs/resources/cases/Case1/images/hospital-background.png b/src/adonisjs/resources/cases/Case1/images/hospital-background.png
new file mode 100644
index 0000000..7f64e05
Binary files /dev/null and b/src/adonisjs/resources/cases/Case1/images/hospital-background.png differ
diff --git a/src/adonisjs/resources/cases/Case1/images/tablet.svg b/src/adonisjs/resources/cases/Case1/images/tablet.svg
new file mode 100644
index 0000000..efb362a
--- /dev/null
+++ b/src/adonisjs/resources/cases/Case1/images/tablet.svg
@@ -0,0 +1,66 @@
+
+
+
+
diff --git a/src/adonisjs/resources/images/dccs/tests/bubble-landscape.png b/src/adonisjs/resources/images/dccs/tests/bubble-landscape.png
new file mode 100644
index 0000000..2836a26
Binary files /dev/null and b/src/adonisjs/resources/images/dccs/tests/bubble-landscape.png differ
diff --git a/src/adonisjs/resources/images/templates/classic/entrance.jpg b/src/adonisjs/resources/images/templates/classic/entrance.jpg
new file mode 100644
index 0000000..1dd4be7
Binary files /dev/null and b/src/adonisjs/resources/images/templates/classic/entrance.jpg differ
diff --git a/src/adonisjs/resources/images/templates/classic/tablet.svg b/src/adonisjs/resources/images/templates/classic/tablet.svg
new file mode 100644
index 0000000..efb362a
--- /dev/null
+++ b/src/adonisjs/resources/images/templates/classic/tablet.svg
@@ -0,0 +1,66 @@
+
+
+
+
diff --git a/src/adonisjs/resources/images/templates/jacinto/entrance.jpg b/src/adonisjs/resources/images/templates/jacinto/entrance.jpg
new file mode 100644
index 0000000..1dd4be7
Binary files /dev/null and b/src/adonisjs/resources/images/templates/jacinto/entrance.jpg differ
diff --git a/src/adonisjs/resources/images/templates/jacinto/hospital-background.png b/src/adonisjs/resources/images/templates/jacinto/hospital-background.png
new file mode 100644
index 0000000..7f64e05
Binary files /dev/null and b/src/adonisjs/resources/images/templates/jacinto/hospital-background.png differ
diff --git a/src/adonisjs/resources/images/templates/jacinto/tablet.svg b/src/adonisjs/resources/images/templates/jacinto/tablet.svg
new file mode 100644
index 0000000..efb362a
--- /dev/null
+++ b/src/adonisjs/resources/images/templates/jacinto/tablet.svg
@@ -0,0 +1,66 @@
+
+
+
+
diff --git a/src/adonisjs/resources/templates/classic/README.md b/src/adonisjs/resources/templates/classic/README.md
new file mode 100644
index 0000000..c69fe6d
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/README.md
@@ -0,0 +1,3 @@
+# Classic Template
+
+Minimal template without extra format.
diff --git a/src/adonisjs/resources/templates/classic/css/player.css b/src/adonisjs/resources/templates/classic/css/player.css
new file mode 100644
index 0000000..77f2fa6
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/css/player.css
@@ -0,0 +1,68 @@
+@charset "UTF-8";
+
+body {
+ font-family: "Trebuchet MS", Helvetica, sans-serif;
+ font-size: 14pt;
+}
+
+.std-border {
+ border: 1px solid lightgray;
+ border-radius: 5px;
+ margin: 5px;
+}
+
+.sty-main-panel {
+ /* the main box (body) occupies all the visible area */
+ position: absolute;
+ left: 0px;
+ right: 0px;
+ top: 0px;
+ bottom: 0px;
+
+ /* eliminate margins etc. */
+ margin: 0px;
+ padding: 0px;
+ border-width: 0px;
+
+ display: flex;
+ flex-direction: column;
+}
+
+.sty-control-panel {
+ flex: 10%;
+ max-height: 48px;
+ display: flex;
+ flex-direction: row;
+}
+
+.control-button {
+ flex: 10%;
+ max-width: 48px;
+ max-height: 48px;
+ margin-right: 10px;
+}
+
+.sty-work-panel {
+ flex: 90%;
+ height: 90%;
+ max-height: 90%;
+ height: 100%;
+ display: flex;
+}
+
+@media (orientation: landscape) {
+ .work-panel {
+ flex-direction: row;
+ }
+}
+
+@media (orientation: portrait) {
+ .work-panel {
+ flex-direction: column;
+ }
+}
+
+.sty-knot-panel {
+ flex: 90%;
+ max-height: 100%;
+}
diff --git a/src/adonisjs/resources/templates/classic/css/presentation.css b/src/adonisjs/resources/templates/classic/css/presentation.css
new file mode 100644
index 0000000..274e255
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/css/presentation.css
@@ -0,0 +1,33 @@
+@charset "UTF-8";
+
+/* Player Panel */
+.sty-player-panel {
+ flex: 10%;
+ max-height: 100%;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+.player-item {
+ max-width: 100%;
+}
+
+/* Knot Rendering */
+
+h1 {
+ text-align: center;
+}
+
+.alert-message {
+ font-size: 20pt;
+ color: blue;
+ font-weight: bold;
+}
+
+.central-buttons {
+ display: flex;
+ flex-direction: row;
+ max-width: 100%;
+ justify-content: center;
+}
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/classic/css/templates.css b/src/adonisjs/resources/templates/classic/css/templates.css
new file mode 100644
index 0000000..fc21ec9
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/css/templates.css
@@ -0,0 +1,140 @@
+@charset "UTF-8";
+
+/* Knot (template) */
+/*******************/
+
+.template-knot {
+ display: flex;
+ flex-direction: column;
+ font-size: 20pt;
+ width: 100%;
+ height: 100%;
+ padding: 20px;
+}
+
+.template-knot p {
+ margin-top: 5px;
+ margin-bottom: 5px;
+ margin-left: 0px;
+ margin-right: 0px;
+}
+
+.template-knot img {
+ max-width: 200px;
+ max-height: 200px;
+}
+
+.template-knot dcc-trigger {
+ display: block;
+ flex: 10%;
+ max-width: 50%;
+}
+
+/* Panel Left Picture (template) */
+/*********************************/
+
+.panel-left-pict {
+ display: flex;
+ flex-direction: row;
+ flex: 100%;
+ max-height: 100%;
+ width: 100%;
+}
+
+.panel-left-pict-image {
+ /*
+ flex-basis: auto;
+ max-height: 100%;
+ width: auto;
+ */
+}
+
+.panel-left-pict-image img {
+ max-height: 100%;
+}
+
+.panel-left-pict-text {
+ /* flex: 70%; */
+}
+
+/* Presentation (template) */
+/***************************/
+
+.template-presentation {
+ display: flex;
+ flex-direction: column;
+ font-size: 20pt;
+ width: 100%;
+}
+
+.template-presentation img, .template-presentation dcc-trigger {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ width: 50%;
+}
+
+/* Tablet (template) */
+/*********************/
+
+.template-tablet {
+ width: 100%;
+ height: 100%;
+
+ position: relative;
+ animation-name: template-tablet-displacement;
+ animation-duration: 2s;
+ background-image: url(../images/tablet.svg);
+ background-repeat: no-repeat;
+ background-size: 100% 100%;
+}
+
+@keyframes template-tablet-displacement {
+ from {left: 100%;}
+ to {left: 0%;}
+}
+
+.template-tablet-inside {
+ display: flex;
+ flex-direction: column;
+ font-size: 20pt;
+ width: auto;
+ height: 90%;
+ padding: 4% 15% 0% 10%;
+ overflow: scrool;
+}
+
+.template-tablet-inside img, .template-tablet-inside dcc-trigger {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ width: 50%;
+}
+
+/* Selector (template) */
+/***********************/
+
+.template-selector {
+ width: 100%;
+ height: 100%;
+
+ background-image: url(../images/tablet.svg);
+ background-repeat: no-repeat;
+ background-size: 100% 100%;
+}
+
+.template-selector-inside {
+ width: auto;
+ height: 90%;
+
+ padding: 4% 15% 0% 10%;
+ overflow: scrool;
+ font-size: 12pt;
+}
+
+.template-selector-inside img, .template-selector-inside dcc-trigger {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ width: 50%;
+}
diff --git a/src/adonisjs/resources/templates/classic/dialog.html b/src/adonisjs/resources/templates/classic/dialog.html
new file mode 100644
index 0000000..dc8a0b4
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/dialog.html
@@ -0,0 +1,3 @@
+
+{knot}
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/classic/entry.html b/src/adonisjs/resources/templates/classic/entry.html
new file mode 100644
index 0000000..1f41665
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/entry.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
Welcome to Phil Muchbetter
+
+
+
+
+
+
+
+
User id (e-mail):
+
Name:
+
+
+
+
+
+
+
+
diff --git a/src/adonisjs/resources/templates/classic/images/entrance.jpg b/src/adonisjs/resources/templates/classic/images/entrance.jpg
new file mode 100644
index 0000000..1dd4be7
Binary files /dev/null and b/src/adonisjs/resources/templates/classic/images/entrance.jpg differ
diff --git a/src/adonisjs/resources/templates/classic/images/tablet.svg b/src/adonisjs/resources/templates/classic/images/tablet.svg
new file mode 100644
index 0000000..efb362a
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/images/tablet.svg
@@ -0,0 +1,66 @@
+
+
+
+
diff --git a/src/adonisjs/resources/templates/classic/imagezoom.html b/src/adonisjs/resources/templates/classic/imagezoom.html
new file mode 100644
index 0000000..8f58e26
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/imagezoom.html
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/adonisjs/resources/templates/classic/knot.html b/src/adonisjs/resources/templates/classic/knot.html
new file mode 100644
index 0000000..9b94125
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/knot.html
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/classic/notice.html b/src/adonisjs/resources/templates/classic/notice.html
new file mode 100644
index 0000000..9946b0d
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/notice.html
@@ -0,0 +1,2 @@
+{knot}
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/classic/presentation.html b/src/adonisjs/resources/templates/classic/presentation.html
new file mode 100644
index 0000000..a513c7f
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/presentation.html
@@ -0,0 +1,3 @@
+
+{knot}
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/classic/register.html b/src/adonisjs/resources/templates/classic/register.html
new file mode 100644
index 0000000..4f6c388
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/register.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
Registration
+
+
+
+
+
+
+
This id already exists.
+
+
+
+
Please, answer all questions.
+
+
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/classic/report.html b/src/adonisjs/resources/templates/classic/report.html
new file mode 100644
index 0000000..c3154c7
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/report.html
@@ -0,0 +1,23 @@
+
+
diff --git a/src/adonisjs/resources/templates/classic/reset.html b/src/adonisjs/resources/templates/classic/reset.html
new file mode 100644
index 0000000..581c72e
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/reset.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
DANGER! Reset Page
+
+
Reset
+
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/classic/selector.html b/src/adonisjs/resources/templates/classic/selector.html
new file mode 100644
index 0000000..da6defd
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/selector.html
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/classic/signin.html b/src/adonisjs/resources/templates/classic/signin.html
new file mode 100644
index 0000000..8010887
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/signin.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
Sign In
+
+
User id (e-mail):
+
+
+
+
+
+
+
+
+
Invalid user id (e-mail). Please, register if you are a new user.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/classic/start.html b/src/adonisjs/resources/templates/classic/start.html
new file mode 100644
index 0000000..98ecb6b
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/start.html
@@ -0,0 +1,2 @@
+
+{knot}
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/classic/tablet.html b/src/adonisjs/resources/templates/classic/tablet.html
new file mode 100644
index 0000000..1932982
--- /dev/null
+++ b/src/adonisjs/resources/templates/classic/tablet.html
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/css/dcc-state-selector.css b/src/adonisjs/resources/templates/jacinto/css/dcc-state-selector.css
new file mode 100644
index 0000000..b1d83c9
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/css/dcc-state-selector.css
@@ -0,0 +1,23 @@
+@charset "UTF-8";
+
+/* Selector DCC */
+
+.dcc-state-selector-template:hover {
+ cursor: pointer;
+}
+
+.dcc-state-selector-0-template {
+ background-color: lightgrey;
+}
+
+.dcc-state-selector-1-template {
+ background-color: green;
+}
+
+.dcc-state-selector-2-template {
+ background-color: blue;
+}
+
+.dcc-state-selector-3-template {
+ background-color: red;
+}
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/css/player.css b/src/adonisjs/resources/templates/jacinto/css/player.css
new file mode 100644
index 0000000..771d805
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/css/player.css
@@ -0,0 +1,75 @@
+@charset "UTF-8";
+
+body {
+ font-family: "Trebuchet MS", Helvetica, sans-serif;
+ font-size: 14pt;
+}
+
+.std-border {
+ border: 1px solid lightgray;
+ border-radius: 5px;
+ margin: 5px;
+}
+
+.sty-main-panel {
+ /* the main box (body) occupies all the visible area */
+ position: absolute;
+ left: 0px;
+ right: 0px;
+ top: 0px;
+ bottom: 0px;
+
+ /* eliminate margins etc. */
+ margin: 0px;
+ padding: 0px;
+ border-width: 0px;
+
+ display: flex;
+ flex-direction: column;
+}
+
+.sty-control-panel {
+ flex: 10%;
+ max-height: 48px;
+ display: flex;
+ flex-direction: row;
+}
+
+.control-button {
+ flex: 10%;
+ max-width: 48px;
+ max-height: 48px;
+ margin-right: 10px;
+}
+
+.sty-work-panel {
+ flex: 90%;
+ height: 90%;
+ max-height: 90%;
+ height: 100%;
+ display: flex;
+}
+
+@media (orientation: landscape) {
+ .work-panel {
+ flex-direction: row;
+ }
+}
+
+@media (orientation: portrait) {
+ .work-panel {
+ flex-direction: column;
+ }
+}
+
+.sty-knot-panel {
+ flex: 90%;
+ max-height: 100%;
+}
+
+.sty-note-panel {
+ border-radius: 1px;
+ box-shadow: 0px 0px 0px 30px rgba(0,0,0,0.5);
+ margin: 10px;
+ background: white;
+}
diff --git a/src/adonisjs/resources/templates/jacinto/css/presentation.css b/src/adonisjs/resources/templates/jacinto/css/presentation.css
new file mode 100644
index 0000000..274e255
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/css/presentation.css
@@ -0,0 +1,33 @@
+@charset "UTF-8";
+
+/* Player Panel */
+.sty-player-panel {
+ flex: 10%;
+ max-height: 100%;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+.player-item {
+ max-width: 100%;
+}
+
+/* Knot Rendering */
+
+h1 {
+ text-align: center;
+}
+
+.alert-message {
+ font-size: 20pt;
+ color: blue;
+ font-weight: bold;
+}
+
+.central-buttons {
+ display: flex;
+ flex-direction: row;
+ max-width: 100%;
+ justify-content: center;
+}
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/css/templates-classic.css b/src/adonisjs/resources/templates/jacinto/css/templates-classic.css
new file mode 100644
index 0000000..d5adccd
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/css/templates-classic.css
@@ -0,0 +1,110 @@
+@charset "UTF-8";
+
+/* Panel Left Picture (template) */
+/*********************************/
+
+.panel-left-pict {
+ display: flex;
+ flex-direction: row;
+ flex: 100%;
+ max-height: 100%;
+ width: 100%;
+}
+
+.panel-left-pict-image {
+ /*
+ flex-basis: auto;
+ max-height: 100%;
+ width: auto;
+ */
+}
+
+.panel-left-pict-image img {
+ max-height: 100%;
+}
+
+.panel-left-pict-text {
+ /* flex: 70%; */
+}
+
+/* Presentation (template) */
+/***************************/
+
+.template-presentation {
+ display: flex;
+ flex-direction: column;
+ font-size: 20pt;
+ width: 100%;
+}
+
+.template-presentation img, .template-presentation dcc-trigger {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ width: 50%;
+}
+
+/* Tablet (template) */
+/*********************/
+
+.template-tablet {
+ width: 100%;
+ height: 100%;
+
+ position: relative;
+ animation-name: template-tablet-displacement;
+ animation-duration: 2s;
+ background-image: url(../images/tablet.svg);
+ background-repeat: no-repeat;
+ background-size: 100% 100%;
+}
+
+@keyframes template-tablet-displacement {
+ from {left: 100%;}
+ to {left: 0%;}
+}
+
+.template-tablet-inside {
+ display: flex;
+ flex-direction: column;
+ font-size: 20pt;
+ width: auto;
+ height: 90%;
+ padding: 4% 15% 0% 10%;
+ overflow: scrool;
+}
+
+.template-tablet-inside img, .template-tablet-inside dcc-trigger {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ width: 50%;
+}
+
+/* Selector (template) */
+/***********************/
+
+.template-selector {
+ width: 100%;
+ height: 100%;
+
+ background-image: url(../images/tablet.svg);
+ background-repeat: no-repeat;
+ background-size: 100% 100%;
+}
+
+.template-selector-inside {
+ width: auto;
+ height: 90%;
+
+ padding: 4% 15% 0% 10%;
+ overflow: scrool;
+ font-size: 12pt;
+}
+
+.template-selector-inside img, .template-selector-inside dcc-trigger {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ width: 50%;
+}
diff --git a/src/adonisjs/resources/templates/jacinto/css/templates.css b/src/adonisjs/resources/templates/jacinto/css/templates.css
new file mode 100644
index 0000000..e0d237a
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/css/templates.css
@@ -0,0 +1,31 @@
+@charset "UTF-8";
+
+/* Template Panels Jacinto */
+/***************************/
+
+/* Trigger DCC */
+
+.dcc-trigger-template {
+ border: 1px solid lightgray;
+ border-radius: 5px;
+ margin: 1px;
+ color: #eeee;
+ padding: 2px 2px;
+ /* text-align: center; */
+ text-decoration: none;
+ display: inline-block;
+}
+.dcc-trigger-template:hover {
+ color: #ffff;
+ font-weight: bold;
+ cursor: pointer;
+}
+
+/* Input DCC */
+
+.dcc-input-template {
+ font-size:28px;
+ font-family:Tahoma, Geneva, sans-serif;
+ fill:#707070;
+ stroke:none;
+}
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/decision_exam.html b/src/adonisjs/resources/templates/jacinto/decision_exam.html
new file mode 100644
index 0000000..cd3c6f0
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/decision_exam.html
@@ -0,0 +1,478 @@
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/detailed.html b/src/adonisjs/resources/templates/jacinto/detailed.html
new file mode 100644
index 0000000..6ca99d1
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/detailed.html
@@ -0,0 +1,375 @@
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/details_eletro.html b/src/adonisjs/resources/templates/jacinto/details_eletro.html
new file mode 100644
index 0000000..5f920f5
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/details_eletro.html
@@ -0,0 +1,589 @@
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/dialog.html b/src/adonisjs/resources/templates/jacinto/dialog.html
new file mode 100644
index 0000000..ad73181
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/dialog.html
@@ -0,0 +1,522 @@
+
+
+ {knot}
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/dialog_left.html b/src/adonisjs/resources/templates/jacinto/dialog_left.html
new file mode 100644
index 0000000..60338c8
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/dialog_left.html
@@ -0,0 +1,263 @@
+
+
+
+ {knot}
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/dialog_right.html b/src/adonisjs/resources/templates/jacinto/dialog_right.html
new file mode 100644
index 0000000..31f1583
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/dialog_right.html
@@ -0,0 +1,520 @@
+
+
+ {knot}
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/entry.html b/src/adonisjs/resources/templates/jacinto/entry.html
new file mode 100644
index 0000000..1f41665
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/entry.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
Welcome to Phil Muchbetter
+
+
+
+
+
+
+
+
User id (e-mail):
+
Name:
+
+
+
+
+
+
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/images/entrance.jpg b/src/adonisjs/resources/templates/jacinto/images/entrance.jpg
new file mode 100644
index 0000000..1dd4be7
Binary files /dev/null and b/src/adonisjs/resources/templates/jacinto/images/entrance.jpg differ
diff --git a/src/adonisjs/resources/templates/jacinto/images/hospital-background.png b/src/adonisjs/resources/templates/jacinto/images/hospital-background.png
new file mode 100644
index 0000000..7f64e05
Binary files /dev/null and b/src/adonisjs/resources/templates/jacinto/images/hospital-background.png differ
diff --git a/src/adonisjs/resources/templates/jacinto/images/tablet.svg b/src/adonisjs/resources/templates/jacinto/images/tablet.svg
new file mode 100644
index 0000000..efb362a
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/images/tablet.svg
@@ -0,0 +1,66 @@
+
+
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/imagezoom.html b/src/adonisjs/resources/templates/jacinto/imagezoom.html
new file mode 100644
index 0000000..8f58e26
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/imagezoom.html
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/information.html b/src/adonisjs/resources/templates/jacinto/information.html
new file mode 100644
index 0000000..6be7ca7
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/information.html
@@ -0,0 +1,407 @@
+
diff --git a/src/adonisjs/resources/templates/jacinto/input.html b/src/adonisjs/resources/templates/jacinto/input.html
new file mode 100644
index 0000000..8dcd5b5
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/input.html
@@ -0,0 +1,318 @@
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/knot.html b/src/adonisjs/resources/templates/jacinto/knot.html
new file mode 100644
index 0000000..0e9a517
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/knot.html
@@ -0,0 +1 @@
+{knot}
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/magnify_exam.html b/src/adonisjs/resources/templates/jacinto/magnify_exam.html
new file mode 100644
index 0000000..70ee1bb
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/magnify_exam.html
@@ -0,0 +1,183 @@
+
+
+
+
+ {knot}
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/marker_exam.html b/src/adonisjs/resources/templates/jacinto/marker_exam.html
new file mode 100644
index 0000000..287cc70
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/marker_exam.html
@@ -0,0 +1,180 @@
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/note.html b/src/adonisjs/resources/templates/jacinto/note.html
new file mode 100644
index 0000000..cd7ff6e
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/note.html
@@ -0,0 +1,157 @@
+
+
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/notice.html b/src/adonisjs/resources/templates/jacinto/notice.html
new file mode 100644
index 0000000..9946b0d
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/notice.html
@@ -0,0 +1,2 @@
+{knot}
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/presentation.html b/src/adonisjs/resources/templates/jacinto/presentation.html
new file mode 100644
index 0000000..a513c7f
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/presentation.html
@@ -0,0 +1,3 @@
+
+{knot}
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/register.html b/src/adonisjs/resources/templates/jacinto/register.html
new file mode 100644
index 0000000..4f6c388
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/register.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
Registration
+
+
+
+
+
+
+
This id already exists.
+
+
+
+
Please, answer all questions.
+
+
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/report.html b/src/adonisjs/resources/templates/jacinto/report.html
new file mode 100644
index 0000000..c3154c7
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/report.html
@@ -0,0 +1,23 @@
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/reset.html b/src/adonisjs/resources/templates/jacinto/reset.html
new file mode 100644
index 0000000..581c72e
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/reset.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
DANGER! Reset Page
+
+
Reset
+
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/selector.html b/src/adonisjs/resources/templates/jacinto/selector.html
new file mode 100644
index 0000000..29684a2
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/selector.html
@@ -0,0 +1,297 @@
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/signin.html b/src/adonisjs/resources/templates/jacinto/signin.html
new file mode 100644
index 0000000..8010887
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/signin.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
Sign In
+
+
User id (e-mail):
+
+
+
+
+
+
+
+
+
Invalid user id (e-mail). Please, register if you are a new user.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/start.html b/src/adonisjs/resources/templates/jacinto/start.html
new file mode 100644
index 0000000..98ecb6b
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/start.html
@@ -0,0 +1,2 @@
+
+{knot}
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/box.svg b/src/adonisjs/resources/templates/jacinto/svgs/box.svg
new file mode 100644
index 0000000..fe1bcb8
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/svgs/box.svg
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/decision.svg b/src/adonisjs/resources/templates/jacinto/svgs/decision.svg
new file mode 100644
index 0000000..79825cd
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/svgs/decision.svg
@@ -0,0 +1,360 @@
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/decision_eletro.svg b/src/adonisjs/resources/templates/jacinto/svgs/decision_eletro.svg
new file mode 100644
index 0000000..9c9e233
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/svgs/decision_eletro.svg
@@ -0,0 +1,462 @@
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/detailed.svg b/src/adonisjs/resources/templates/jacinto/svgs/detailed.svg
new file mode 100644
index 0000000..69616b4
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/svgs/detailed.svg
@@ -0,0 +1,572 @@
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/dialog_left.svg b/src/adonisjs/resources/templates/jacinto/svgs/dialog_left.svg
new file mode 100644
index 0000000..e5b225a
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/svgs/dialog_left.svg
@@ -0,0 +1,260 @@
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/dialog_right.svg b/src/adonisjs/resources/templates/jacinto/svgs/dialog_right.svg
new file mode 100644
index 0000000..d2d618f
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/svgs/dialog_right.svg
@@ -0,0 +1,517 @@
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/images/hospital-background.png b/src/adonisjs/resources/templates/jacinto/svgs/images/hospital-background.png
new file mode 100644
index 0000000..7f64e05
Binary files /dev/null and b/src/adonisjs/resources/templates/jacinto/svgs/images/hospital-background.png differ
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/images/nurse_agnes.png b/src/adonisjs/resources/templates/jacinto/svgs/images/nurse_agnes.png
new file mode 100644
index 0000000..f4ab542
Binary files /dev/null and b/src/adonisjs/resources/templates/jacinto/svgs/images/nurse_agnes.png differ
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/images/patient_jakob.png b/src/adonisjs/resources/templates/jacinto/svgs/images/patient_jakob.png
new file mode 100644
index 0000000..4e49da7
Binary files /dev/null and b/src/adonisjs/resources/templates/jacinto/svgs/images/patient_jakob.png differ
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/images/supervisor_harry.png b/src/adonisjs/resources/templates/jacinto/svgs/images/supervisor_harry.png
new file mode 100644
index 0000000..ce0c3dc
Binary files /dev/null and b/src/adonisjs/resources/templates/jacinto/svgs/images/supervisor_harry.png differ
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/information.svg b/src/adonisjs/resources/templates/jacinto/svgs/information.svg
new file mode 100644
index 0000000..3a07208
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/svgs/information.svg
@@ -0,0 +1,605 @@
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/input.svg b/src/adonisjs/resources/templates/jacinto/svgs/input.svg
new file mode 100644
index 0000000..1d3e213
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/svgs/input.svg
@@ -0,0 +1,330 @@
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/magnify_exam-wide.svg b/src/adonisjs/resources/templates/jacinto/svgs/magnify_exam-wide.svg
new file mode 100644
index 0000000..75f63ba
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/svgs/magnify_exam-wide.svg
@@ -0,0 +1,174 @@
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/magnify_exam.svg b/src/adonisjs/resources/templates/jacinto/svgs/magnify_exam.svg
new file mode 100755
index 0000000..d55c86b
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/svgs/magnify_exam.svg
@@ -0,0 +1,62 @@
+
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/note.svg b/src/adonisjs/resources/templates/jacinto/svgs/note.svg
new file mode 100644
index 0000000..1934fcb
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/svgs/note.svg
@@ -0,0 +1,180 @@
+
+
diff --git a/src/adonisjs/resources/templates/jacinto/svgs/zoom_exam.png b/src/adonisjs/resources/templates/jacinto/svgs/zoom_exam.png
new file mode 100755
index 0000000..5d5f92b
Binary files /dev/null and b/src/adonisjs/resources/templates/jacinto/svgs/zoom_exam.png differ
diff --git a/src/adonisjs/resources/templates/jacinto/tablet.html b/src/adonisjs/resources/templates/jacinto/tablet.html
new file mode 100644
index 0000000..1932982
--- /dev/null
+++ b/src/adonisjs/resources/templates/jacinto/tablet.html
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/zombie/case.html b/src/adonisjs/resources/templates/zombie/case.html
new file mode 100644
index 0000000..f609db8
--- /dev/null
+++ b/src/adonisjs/resources/templates/zombie/case.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/zombie/css/player.css b/src/adonisjs/resources/templates/zombie/css/player.css
new file mode 100644
index 0000000..5c2c214
--- /dev/null
+++ b/src/adonisjs/resources/templates/zombie/css/player.css
@@ -0,0 +1,46 @@
+@charset "UTF-8";
+
+body {
+ font-family: "Trebuchet MS", Helvetica, sans-serif;
+ font-size: 14pt;
+}
+
+.sty-main-panel {
+ /* the main box (body) occupies all the visible area */
+ position: absolute;
+ left: 0px;
+ right: 0px;
+ top: 0px;
+ bottom: 0px;
+
+ /* eliminate margins etc. */
+ margin: 0px;
+ padding: 0px;
+ border-width: 0px;
+
+ display: flex;
+ flex-direction: column;
+}
+
+.panel_center {
+ position: absolute;
+ width: 100%;
+ top: 0px;
+ bottom: 0px;
+ left: 0px;
+ right: 0px;
+ margin-top: 60px;
+ background-color: transparent;
+}
+
+.panel_inner_center {
+ position: absolute;
+ top: 0px;
+ bottom: 0px;
+ left: 0px;
+ right: 0px;
+ margin-left: 10%;
+ margin-right: 10%;
+ background-color: #fbfcd2;
+}
+
diff --git a/src/adonisjs/resources/templates/zombie/css/presentation.css b/src/adonisjs/resources/templates/zombie/css/presentation.css
new file mode 100644
index 0000000..5518ccb
--- /dev/null
+++ b/src/adonisjs/resources/templates/zombie/css/presentation.css
@@ -0,0 +1,176 @@
+@charset "UTF-8";
+
+body {
+ font-family: "Trebuchet MS", Helvetica, sans-serif;
+ margin: 0px;
+ background-color: #383f4f;
+}
+
+/* panels */
+/* ------ */
+
+.panel_north {
+ position: relative;
+ width: 100%;
+ height: 100px;
+ overflow: auto;
+ color: #383f4f;
+ background-color: #c4ad9d;
+}
+
+/* main menu */
+/* --------- */
+.main_menu
+{
+ position: relative;
+ float: right;
+ width: auto;
+ height: auto;
+ padding: 10px;
+ font-size: 16pt;
+ color: #383f4f;
+}
+
+.main_menu a:link {
+ color: #383f4f;
+ text-decoration: none;
+}
+
+.main_menu a:visited {
+ color: #383f4f;
+ text-decoration: none;
+}
+
+.main_menu a:hover {
+ color: #383f4f;
+ text-decoration: none;
+}
+
+.main_menu hr {
+ border: 1px solid;
+}
+
+/* home item */
+/* --------- */
+
+.home_item {
+ position: relative;
+ float: left;
+ height: 50px;
+ margin: 10px;
+ font-size: 24pt;
+}
+
+.home_item a:link {
+ color: #383f4f;
+ text-decoration: none;
+}
+
+.home_item a:visited {
+ color: #383f4f;
+ text-decoration: none;
+}
+
+.home_item a:hover {
+ color: #383f4f;
+ text-decoration: none;
+}
+
+/* iFrames */
+/* ------- */
+
+.iframe_render {
+ width: 100%;
+ height: 100%;
+ margin: 0px auto;
+ padding: 0px;
+}
+
+
+
+/* PAGE.CSS */
+
+.panel_presentation {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ color: #383f4f;
+}
+
+.panel_image {
+ width: auto;
+ height: 100%;
+ top: 0px;
+ left: 0px;
+ margin: 0px;
+ padding: 0px;
+ overflow: hidden;
+}
+
+.image_presentation {
+ position: relative;
+ width: auto;
+ height: 100%;
+ top: 0px;
+ left: 0px;
+ background-color: transparent;
+}
+
+.panel_case {
+ width: auto;
+ height: auto;
+ top: 0px;
+ right: 0px;
+ margin: 0px;
+ padding: 0px;
+ overflow: hidden;
+}
+
+.case_title {
+ position: relative;
+ float: top;
+ width: 100%;
+ height: auto;
+ padding: 30px;
+ font-size: 24pt;
+}
+
+.case_text {
+ font-size: 18pt;
+ padding: 30px;
+}
+
+/* case link */
+/* --------- */
+
+.case_link {
+ color: #e0e9ce;
+ text-align: center;
+ width: 300px;
+ height: 30px;
+ margin-left: auto;
+ margin-right: 20px;
+ margin-top: 20px;
+ margin-bottom: 20px;
+ background-color: #383f4f;
+ font-size: 16pt;
+}
+
+.case_link a:link {
+ color: #e0e9ce;
+ text-decoration: none;
+}
+
+.case_link a:visited {
+ color: #e0e9ce;
+ text-decoration: none;
+}
+
+.case_link a:hover {
+ color: #e0e9ce;
+ text-decoration: none;
+}
diff --git a/src/adonisjs/resources/templates/zombie/css/templates-classic.css b/src/adonisjs/resources/templates/zombie/css/templates-classic.css
new file mode 100644
index 0000000..d5adccd
--- /dev/null
+++ b/src/adonisjs/resources/templates/zombie/css/templates-classic.css
@@ -0,0 +1,110 @@
+@charset "UTF-8";
+
+/* Panel Left Picture (template) */
+/*********************************/
+
+.panel-left-pict {
+ display: flex;
+ flex-direction: row;
+ flex: 100%;
+ max-height: 100%;
+ width: 100%;
+}
+
+.panel-left-pict-image {
+ /*
+ flex-basis: auto;
+ max-height: 100%;
+ width: auto;
+ */
+}
+
+.panel-left-pict-image img {
+ max-height: 100%;
+}
+
+.panel-left-pict-text {
+ /* flex: 70%; */
+}
+
+/* Presentation (template) */
+/***************************/
+
+.template-presentation {
+ display: flex;
+ flex-direction: column;
+ font-size: 20pt;
+ width: 100%;
+}
+
+.template-presentation img, .template-presentation dcc-trigger {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ width: 50%;
+}
+
+/* Tablet (template) */
+/*********************/
+
+.template-tablet {
+ width: 100%;
+ height: 100%;
+
+ position: relative;
+ animation-name: template-tablet-displacement;
+ animation-duration: 2s;
+ background-image: url(../images/tablet.svg);
+ background-repeat: no-repeat;
+ background-size: 100% 100%;
+}
+
+@keyframes template-tablet-displacement {
+ from {left: 100%;}
+ to {left: 0%;}
+}
+
+.template-tablet-inside {
+ display: flex;
+ flex-direction: column;
+ font-size: 20pt;
+ width: auto;
+ height: 90%;
+ padding: 4% 15% 0% 10%;
+ overflow: scrool;
+}
+
+.template-tablet-inside img, .template-tablet-inside dcc-trigger {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ width: 50%;
+}
+
+/* Selector (template) */
+/***********************/
+
+.template-selector {
+ width: 100%;
+ height: 100%;
+
+ background-image: url(../images/tablet.svg);
+ background-repeat: no-repeat;
+ background-size: 100% 100%;
+}
+
+.template-selector-inside {
+ width: auto;
+ height: 90%;
+
+ padding: 4% 15% 0% 10%;
+ overflow: scrool;
+ font-size: 12pt;
+}
+
+.template-selector-inside img, .template-selector-inside dcc-trigger {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ width: 50%;
+}
diff --git a/src/adonisjs/resources/templates/zombie/css/templates.css b/src/adonisjs/resources/templates/zombie/css/templates.css
new file mode 100644
index 0000000..5ea51bb
--- /dev/null
+++ b/src/adonisjs/resources/templates/zombie/css/templates.css
@@ -0,0 +1,53 @@
+@charset "UTF-8";
+
+/* Template Panels Jacinto */
+/***************************/
+
+/* Trigger DCC */
+
+.dcc-trigger-template {
+ border: 1px solid lightgray;
+ border-radius: 5px;
+ margin: 5px;
+ color: #eeee;
+ padding: 14px 25px;
+ text-align: center;
+ text-decoration: none;
+ display: inline-block;
+}
+.dcc-trigger-template:hover {
+ color: #ffff;
+ font-weight: bold;
+ cursor: pointer;
+}
+
+/* Input DCC */
+
+.dcc-input-template {
+ font-size:28px;
+ font-family:Tahoma, Geneva, sans-serif;
+ fill:#707070;
+ stroke:none;
+}
+
+/* Selector DCC */
+
+.dcc-state-selector-template:hover {
+ cursor: pointer;
+}
+
+.dcc-state-selector-0-template {
+ background-color: lightgrey;
+}
+
+.dcc-state-selector-1-template {
+ background-color: green;
+}
+
+.dcc-state-selector-2-template {
+ background-color: blue;
+}
+
+.dcc-state-selector-3-template {
+ background-color: red;
+}
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/zombie/end.html b/src/adonisjs/resources/templates/zombie/end.html
new file mode 100644
index 0000000..49d883e
--- /dev/null
+++ b/src/adonisjs/resources/templates/zombie/end.html
@@ -0,0 +1,10 @@
+
+
+
+
+
{knot}
+
Placar: pontos
+
+
+
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/zombie/entry.html b/src/adonisjs/resources/templates/zombie/entry.html
new file mode 100644
index 0000000..f198b73
--- /dev/null
+++ b/src/adonisjs/resources/templates/zombie/entry.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
Zombie Health
+
+
+
+
+
+
+
+
+
+
Você é um Médico Girafa (girafas não viram zumbis).
+
+
+
+
+
+
+
+
Este nome fantasia já existe.
+
+
+
+
Por favor, responda todas as questões.
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/zombie/knot.html b/src/adonisjs/resources/templates/zombie/knot.html
new file mode 100644
index 0000000..a711c39
--- /dev/null
+++ b/src/adonisjs/resources/templates/zombie/knot.html
@@ -0,0 +1,8 @@
+
diff --git a/src/adonisjs/resources/templates/zombie/notice.html b/src/adonisjs/resources/templates/zombie/notice.html
new file mode 100644
index 0000000..e6f81f5
--- /dev/null
+++ b/src/adonisjs/resources/templates/zombie/notice.html
@@ -0,0 +1,12 @@
+
+
diff --git a/src/adonisjs/resources/templates/zombie/notice_right.html b/src/adonisjs/resources/templates/zombie/notice_right.html
new file mode 100644
index 0000000..98d3510
--- /dev/null
+++ b/src/adonisjs/resources/templates/zombie/notice_right.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ {knot}
+
Placar: pontos
+
+
+
+
+
diff --git a/src/adonisjs/resources/templates/zombie/notice_wrong.html b/src/adonisjs/resources/templates/zombie/notice_wrong.html
new file mode 100644
index 0000000..86c5591
--- /dev/null
+++ b/src/adonisjs/resources/templates/zombie/notice_wrong.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ {knot}
+
Placar: pontos
+
+
+
+
+
diff --git a/src/adonisjs/resources/templates/zombie/presentation.html b/src/adonisjs/resources/templates/zombie/presentation.html
new file mode 100644
index 0000000..cd54fea
--- /dev/null
+++ b/src/adonisjs/resources/templates/zombie/presentation.html
@@ -0,0 +1,10 @@
+
+
+
{title}
+
+
+{knot}
+
+
+
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/templates/zombie/report.html b/src/adonisjs/resources/templates/zombie/report.html
new file mode 100644
index 0000000..5543c7f
--- /dev/null
+++ b/src/adonisjs/resources/templates/zombie/report.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/adonisjs/resources/views/dt.edge b/src/adonisjs/resources/views/dt.edge
new file mode 100644
index 0000000..f3dbff3
--- /dev/null
+++ b/src/adonisjs/resources/views/dt.edge
@@ -0,0 +1,3 @@
+Hello World!
+
+{{knot}}
diff --git a/src/adonisjs/resources/views/themes/classic/dt.edge b/src/adonisjs/resources/views/themes/classic/dt.edge
new file mode 100644
index 0000000..f3dbff3
--- /dev/null
+++ b/src/adonisjs/resources/views/themes/classic/dt.edge
@@ -0,0 +1,3 @@
+Hello World!
+
+{{knot}}
diff --git a/src/adonisjs/resources/views/themes/classic/home.edge b/src/adonisjs/resources/views/themes/classic/home.edge
new file mode 100644
index 0000000..e69de29
diff --git a/src/adonisjs/resources/views/themes/jacinto/dt.edge b/src/adonisjs/resources/views/themes/jacinto/dt.edge
new file mode 100644
index 0000000..ada192c
--- /dev/null
+++ b/src/adonisjs/resources/views/themes/jacinto/dt.edge
@@ -0,0 +1,3 @@
+Hello World!
+
+{{knot}}
diff --git a/src/adonisjs/start/routes.js b/src/adonisjs/start/routes.js
index 02059f3..b73073e 100644
--- a/src/adonisjs/start/routes.js
+++ b/src/adonisjs/start/routes.js
@@ -1,108 +1,128 @@
'use strict'
+
+const Route = use('Route')
+
/*
-|--------------------------------------------------------------------------
-| Routes
-|--------------------------------------------------------------------------
-|
-| Http routes are entry points to your web application. You can create
-| routes for different URL's and bind Controller actions to them.
-|
-| A complete guide on routing is available here.
-| http://adonisjs.com/docs/4.1/routing
-|
-| Architecture Documentation: https://docs.google.com/presentation/d/1-8s0X-VuXF4b_vi8tbzYNCHU6UwYOUPa7KppUpevaNA/edit#slide=id.g4cba6f4dfb_0_108
-| case-notebook previous mapping: https://github.com/datasci4health/case-notebook/blob/master/notebook/server/notebook-server-rest.ipynb
+|----------------------------------------------------------------------------------------------
+| index
+|----------------------------------------------------------------------------------------------
*/
+Route.get('/', () => { return 'Hello from the harena-manager'} )
-/** @type {typeof import('@adonisjs/framework/src/Route/Manager')} */
-const Route = use('Route')
-Route.get('/', () => { return 'Hello from the Harena\'s casemanager'} )
-/*
- User CRUD
+/*
+|----------------------------------------------------------------------------------------------
+| api: v1
+| resource: /user
+|----------------------------------------------------------------------------------------------
*/
+Route.post('/api/v1/user/register', 'v1/UserController.store')
+Route.post('/api/v1/user/login', 'AuthController.login')
Route.group(() => {
- Route.get( '', 'v1/UserController.index')
- Route.get( ':id', 'v1/UserController.show')
- Route.put( ':id', 'v1/UserController.update')
- Route.delete(':id', 'v1/UserController.destroy')
- Route.get( ':id/cases', 'v1/UserController.listCases')
-
- Route.get( ':id/executions', 'v1/UserController.listExecutions')
- Route.post( 'executions', 'v1/UserController.newExecution') // input: case_id -> returns execution:{uuid}
+
+ Route.get( '', 'v1/UserController.index')
+ Route.get( ':id', 'v1/UserController.show')
+ Route.put( ':id', 'v1/UserController.update')
+ Route.delete(':id', 'v1/UserController.destroy')
+ Route.get( ':id/execution', 'v1/UserController.listExecutions')
+ Route.post( 'execution', 'v1/UserController.newExecution')
+
}).prefix('/api/v1/user').middleware('auth')
-/*
- Case CRUD
+
+
+/*
+|----------------------------------------------------------------------------------------------
+| api: v1
+| resource: /case
+|----------------------------------------------------------------------------------------------
*/
Route.group(() => {
- Route.get( '', 'v1/CaseController.index')
- Route.get( ':id', 'v1/CaseController.show')
- Route.post( '', 'v1/CaseController.store')
- Route.put( ':id', 'v1/CaseController.update')
- Route.delete(':id', 'v1/CaseController.destroy')
-
- Route.post( 'new', 'v1/CaseController.newCase')
- Route.post( 'load-case', 'v1/CaseController.loadCase')
- Route.post( 'rename-case', 'v1/CaseController.renameCase')
-
- Route.post( ':id/executions', 'v1/UserController.newExecution') // input: user_id -> returns execution:{uuid}
- Route.get( ':id/executions', 'v1/UserController.listExecutions') // input: user_id -> returns execution:{uuid}
-
- Route.post( 'rename-case', 'v1/CaseController.prepare-case-html')
- Route.post( 'prepare-case-html', 'v1/CaseController.prepareCaseHTML')
-}).prefix('/api/v1/cases/').middleware('auth')
-//}).prefix('/api/v1/case/').middleware('auth')
-
-/*
- Execution CRUD
+
+ Route.post( 'list', 'v1/CaseController.index')
+ Route.get( ':id', 'v1/CaseController.show')
+ Route.post( '', 'v1/CaseController.store')
+ Route.put( ':id', 'v1/CaseController.update')
+ Route.delete(':id', 'v1/CaseController.destroy')
+ Route.post( 'new', 'v1/CaseController.newCase')
+ Route.post( ':id/executions', 'v1/UserController.newExecution')
+ Route.get( ':id/executions', 'v1/UserController.listExecutions')
+
+}).prefix('/api/v1/case').middleware('auth')
+
+
+
+/*
+|----------------------------------------------------------------------------------------------
+| api: v1
+| resource: /execution
+|----------------------------------------------------------------------------------------------
*/
Route.group(() => {
- Route.get( '', 'v1/ExecutionController.index') // {filter:{ user_id: 14, case_id: 89}}
- Route.get( ':id', 'v1/ExecutionController.index')
- Route.put( ':id', 'v1/ExecutionController.update')
- Route.delete(':id', 'v1/ExecutionController.destroy')
+
+ Route.get( '', 'v1/ExecutionController.index')
+ Route.get( ':id', 'v1/ExecutionController.index')
+ Route.put( ':id', 'v1/ExecutionController.update')
+ Route.delete(':id', 'v1/ExecutionController.destroy')
+
}).prefix('/api/v1/execution/').middleware('auth')
-/*
- Template CRUD
+
+
+/*
+|----------------------------------------------------------------------------------------------
+| api: v1
+| resource: /template
+|----------------------------------------------------------------------------------------------
*/
Route.group(() => {
- Route.get( '', 'v1/TemplateController.index')
+
+ Route.get( '', 'v1/TemplateController.index')
+
}).prefix('/api/v1/template/').middleware('auth')
-/*
- Template CRUD
-*/
-//Route.group(() => {
-// Route.get( '', 'v1/TemplateController.index')
-//}).prefix('/api/v1/style/').middleware('auth')
-/*
- Models CRUD
+
+/*
+|----------------------------------------------------------------------------------------------
+| api: v1
+| resource: /models
+|----------------------------------------------------------------------------------------------
*/
Route.group(() => {
- Route.get( '', 'v1/ModelController.index')
+
+ Route.get( '', 'v1/ModelController.index')
+
}).prefix('/api/v1/models/').middleware('auth')
-// Route.group(() => {
-// Route.get( '', 'v1/ModelController.index')
-// }).prefix('/api/v1/template/').middleware('auth')
-/*
- KnotCapsule CRUD
+
+/*
+|----------------------------------------------------------------------------------------------
+| api: v1
+| resource: /knot
+|----------------------------------------------------------------------------------------------
*/
Route.group(() => {
- Route.get( '', 'v1/KnotCapsuleController.index')
- Route.post( '', 'v1/KnotCapsuleController.store')
+
+ Route.get( '', 'v1/KnotCapsuleController.index')
+ Route.post( '', 'v1/KnotCapsuleController.store')
+
}).prefix('/api/v1/knot/').middleware('auth')
-/*
- Auth
+
+
+/*
+|----------------------------------------------------------------------------------------------
+| api: v1
+| resource: /artifacts
+|----------------------------------------------------------------------------------------------
*/
Route.group(() => {
- Route.post('register', 'v1/UserController.store')
- Route.post('login', 'AuthController.login')
-}).prefix('/api/v1/auth')
+
+ Route.post( '', 'v1/ArtifactController.store')
+
+}).prefix('/api/v1/artifact/').middleware('auth')
+