From 6bb05dc4b2d7922191a6e92bd0253361e21eeef6 Mon Sep 17 00:00:00 2001 From: Zahen Malla Osman <zahen.malla-osman@abolis.fr> Date: Fri, 22 Feb 2019 11:51:23 +0100 Subject: [PATCH 01/10] Put back package.json in dist. "A package must contain a package.json file in order to be published to the npm registry": https://docs.npmjs.com/about-packages-and-modules#about-packages --- dist/package.json | 49 +++++++++++++++++++++++++++++++++++++++++++++++ gulpfile.js | 8 +++++++- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 dist/package.json diff --git a/dist/package.json b/dist/package.json new file mode 100644 index 0000000..4f0efc3 --- /dev/null +++ b/dist/package.json @@ -0,0 +1,49 @@ +{ + "name": "plate-map", + "version": "1.0.2", + "description": "JavaScript Plate Layout is an open source tool developed collaboratively by [Chai Biotechnologies](www.chaibio.com) and [New England Biolabs](www.neb.com) for visualizing and editing the layout of scientific assay plates.", + "scripts": { + "build.dist": "gulp build.dist", + "build.dev": "gulp build.dev", + "serve.dev": "gulp serve.dev", + "build.prod": "gulp build.prod", + "serve.prod": "gulp serve.prod", + "start": "gulp serve.dev" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/nebiolabs/plate-map.git" + }, + "main": "dist/js/plate-map.js", + "style": "dist/css/plate-map.css", + "keywords": [], + "author": "Langhorst, Brad <Langhorst@neb.com>", + "license": "AGPL-3.0-only", + "bugs": { + "url": "https://github.com/nebiolabs/plate-map/issues" + }, + "homepage": "https://github.com/nebiolabs/plate-map#readme", + "dependencies": { + "bootstrap": "^4.1.3", + "clipboard": "^2.0.4", + "fabric": "^2.6.0", + "jquery": "^3.3.1", + "jquery-ui-dist": "^1.12.1", + "popper.js": "^1.14.7", + "select2": "^3.5.1" + }, + "devDependencies": { + "browser-sync": "^2.26.3", + "del": "^3.0.0", + "gulp": "^4.0.0", + "gulp-clean-css": "^4.0.0", + "gulp-concat": "^2.6.1", + "gulp-connect": "^5.7.0", + "gulp-htmlmin": "^5.0.1", + "gulp-inject": "^5.0.2", + "gulp-rename": "^1.4.0", + "gulp-uglify": "^3.0.1", + "merge-stream": "^1.0.1", + "run-sequence": "^2.2.1" + } +} diff --git a/gulpfile.js b/gulpfile.js index b8dba8e..af87bc4 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -99,6 +99,7 @@ gulp.task('config.pack', async () => { config.source.css = PATH.source.app.css; config.source.js = PATH.source.app.js; config.source.js.push('!src/js/example.js'); + config.source.json = PATH.source.app.json; config.destination.css = PATH.destination.pack.css; config.destination.js = PATH.destination.pack.js; config.destination.root = PATH.destination.pack.root; @@ -130,6 +131,11 @@ gulp.task('copy.img', () => { .pipe(gulp.dest(config.destination.css)); }); +gulp.task('copy.package.json', () => { + return gulp.src(config.source.json) + .pipe(gulp.dest(config.destination.root)); +}); + gulp.task('inject.prod', () => { return gulp.src(config.source.html) .pipe(inject(gulp.src([`${config.destination.css}/*.min.css`, `${config.destination.js}/*.min.js`], {read: false}), @@ -176,7 +182,7 @@ gulp.task('server.prod', async () => { }); }); -gulp.task('build.dist', gulp.series('config.pack', 'clean', 'css', 'js')); +gulp.task('build.dist', gulp.series('config.pack', 'clean', 'css', 'js', 'copy.package.json')); gulp.task('build.dev', gulp.series('config.dev', 'clean', 'copy.src', 'copy.img', 'inject.dev')); From 441e6a9b31bc4bcfaac72ba234f7db0011e27885 Mon Sep 17 00:00:00 2001 From: Zahen Malla Osman <zahen.malla-osman@abolis.fr> Date: Fri, 22 Feb 2019 12:12:58 +0100 Subject: [PATCH 02/10] Fix serve.dev in gulpfile.js --- gulpfile.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index af87bc4..bcb554c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -171,8 +171,7 @@ gulp.task('inject.dev', () => { gulp.task('server.dev', async () => { browserSync.init({server: PATH.destination.dev.root}); - gulp.watch([PATH.source.app.css, PATH.source.app.js], ['build.dev']) - .on('change', browserSync.reload); + gulp.watch(PATH.source.app.css.concat(PATH.source.app.js), gulp.series('build.dev', browserSync.reload)); }); gulp.task('server.prod', async () => { From 51faff617e0e57fd339f5674a02436c10dc8dd0d Mon Sep 17 00:00:00 2001 From: Zahen Malla Osman <zahen.malla-osman@abolis.fr> Date: Fri, 1 Mar 2019 12:10:44 +0100 Subject: [PATCH 03/10] Remove package.json from dist again --- dist/package.json | 49 ----------------------------------------------- gulpfile.js | 11 ++--------- 2 files changed, 2 insertions(+), 58 deletions(-) delete mode 100644 dist/package.json diff --git a/dist/package.json b/dist/package.json deleted file mode 100644 index 4f0efc3..0000000 --- a/dist/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "plate-map", - "version": "1.0.2", - "description": "JavaScript Plate Layout is an open source tool developed collaboratively by [Chai Biotechnologies](www.chaibio.com) and [New England Biolabs](www.neb.com) for visualizing and editing the layout of scientific assay plates.", - "scripts": { - "build.dist": "gulp build.dist", - "build.dev": "gulp build.dev", - "serve.dev": "gulp serve.dev", - "build.prod": "gulp build.prod", - "serve.prod": "gulp serve.prod", - "start": "gulp serve.dev" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/nebiolabs/plate-map.git" - }, - "main": "dist/js/plate-map.js", - "style": "dist/css/plate-map.css", - "keywords": [], - "author": "Langhorst, Brad <Langhorst@neb.com>", - "license": "AGPL-3.0-only", - "bugs": { - "url": "https://github.com/nebiolabs/plate-map/issues" - }, - "homepage": "https://github.com/nebiolabs/plate-map#readme", - "dependencies": { - "bootstrap": "^4.1.3", - "clipboard": "^2.0.4", - "fabric": "^2.6.0", - "jquery": "^3.3.1", - "jquery-ui-dist": "^1.12.1", - "popper.js": "^1.14.7", - "select2": "^3.5.1" - }, - "devDependencies": { - "browser-sync": "^2.26.3", - "del": "^3.0.0", - "gulp": "^4.0.0", - "gulp-clean-css": "^4.0.0", - "gulp-concat": "^2.6.1", - "gulp-connect": "^5.7.0", - "gulp-htmlmin": "^5.0.1", - "gulp-inject": "^5.0.2", - "gulp-rename": "^1.4.0", - "gulp-uglify": "^3.0.1", - "merge-stream": "^1.0.1", - "run-sequence": "^2.2.1" - } -} diff --git a/gulpfile.js b/gulpfile.js index bcb554c..0025657 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -16,8 +16,7 @@ const PATH = { app: { css: ['src/css/*.css'], js: ['src/js/*.js'], - html: 'src/index.html', - json: 'package.json' + html: 'src/index.html' }, dependencies: { css: [ @@ -99,7 +98,6 @@ gulp.task('config.pack', async () => { config.source.css = PATH.source.app.css; config.source.js = PATH.source.app.js; config.source.js.push('!src/js/example.js'); - config.source.json = PATH.source.app.json; config.destination.css = PATH.destination.pack.css; config.destination.js = PATH.destination.pack.js; config.destination.root = PATH.destination.pack.root; @@ -131,11 +129,6 @@ gulp.task('copy.img', () => { .pipe(gulp.dest(config.destination.css)); }); -gulp.task('copy.package.json', () => { - return gulp.src(config.source.json) - .pipe(gulp.dest(config.destination.root)); -}); - gulp.task('inject.prod', () => { return gulp.src(config.source.html) .pipe(inject(gulp.src([`${config.destination.css}/*.min.css`, `${config.destination.js}/*.min.js`], {read: false}), @@ -181,7 +174,7 @@ gulp.task('server.prod', async () => { }); }); -gulp.task('build.dist', gulp.series('config.pack', 'clean', 'css', 'js', 'copy.package.json')); +gulp.task('build.dist', gulp.series('config.pack', 'clean', 'css', 'js')); gulp.task('build.dev', gulp.series('config.dev', 'clean', 'copy.src', 'copy.img', 'inject.dev')); From 7466d0ce379ec8302f7c815177ac9b8679293229 Mon Sep 17 00:00:00 2001 From: Zahen Malla Osman <zahen.malla-osman@abolis.fr> Date: Fri, 8 Feb 2019 17:38:23 +0100 Subject: [PATCH 04/10] Scroll to group in the bottom table on single well selection --- README.md | 16 +- dist/css/plate-map.css | 491 ---- dist/css/plate-map.min.css | 2 - dist/css/plate-map.min.css.map | 1 - dist/js/plate-map.js | 4360 -------------------------------- dist/js/plate-map.min.js | 2 - dist/js/plate-map.min.js.map | 1 - src/js/bottom-table.js | 2 +- src/js/engine.js | 4 +- src/js/example.js | 1 + src/js/fabric-events.js | 3 + src/js/plate-layout.js | 582 +++-- 12 files changed, 324 insertions(+), 5141 deletions(-) delete mode 100644 dist/css/plate-map.css delete mode 100644 dist/css/plate-map.min.css delete mode 100644 dist/css/plate-map.min.css.map delete mode 100755 dist/js/plate-map.js delete mode 100755 dist/js/plate-map.min.js delete mode 100644 dist/js/plate-map.min.js.map diff --git a/README.md b/README.md index c3cba77..2cdd6c0 100644 --- a/README.md +++ b/README.md @@ -467,20 +467,10 @@ options for subfield id `raw_value` will be `["unit1", "unit2"]` , which is used ## Requirements **Note** that this project was tested with _Node_ v9.10.1 and _NPM_ v5.6.0. -If this is your first time, start by installing the npm dependencies: `npm install` +If this is your first time: +1. install the (os) dependencies of the `canvas` library: https://www.npmjs.com/package/canvas/v/1.6.11 +2. run `npm install` in this directory -Building this project also requires the libraries _gif_lib_ and _jpeg_lib_ (required the _Canvas_ npm package). - -- On Linux/Ubuntu : - ```bash - sudo apt install libgif-dev - sudo apt install libjpeg-dev - ``` -- On Mac OS : - ```bash - brew install giflib - brew install libjpeg - ``` ## Project Structure ``` diff --git a/dist/css/plate-map.css b/dist/css/plate-map.css deleted file mode 100644 index f44a69c..0000000 --- a/dist/css/plate-map.css +++ /dev/null @@ -1,491 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Roboto); - -.plate-setup-container { - width: 1024px; - height: 768px; - position: relative; - float: left; -} - -.plate-setup-wrapper { - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - flex-direction: column; - background-color: #f5f5f5; -} - -.plate-setup-top-section { - height: 540px; - top: 0; - left: 0; - right: 0; - position: absolute; -} - -.plate-setup-top-left { - width: 674px; - top: 0; - bottom: 0; - position: absolute; -} - -.plate-setup-top-right { - left: 674px; - top: 0; - bottom: 0; - right: 0; - position: absolute; -} - -.plate-setup-overlay-container { - height: 32px; - top: 10px; - left: 16px; - right: 16px; - position: inherit; - background-color: #464646; - border-radius: 2px; - display: flex; - justify-content: space-between; - align-items: baseline; - vertical-align: middle; -} - -.plate-setup-overlay-radio-container { - width: 32px; - height: 32px; -} - -.plate-setup-overlay-text-container { - color: white; - font-size: 12px; - line-height: 30px; - height: 32px; - font-family: "Roboto", Arial, sans-serif; - margin: 2px 8px; - flex: 1 1 auto; -} - -.plate-setup-overlay-button-container, .plate-setup-overlay-bottom-button-container { - flex: 0 0 auto; - display: flex; - flex: 1 1 0; -} - -.plate-setup-button { - height: 23px; - font-family: "Roboto", Arial, sans-serif; - font-size: 12px; - border: none; - background-color: white; - border-radius: 2px; - margin-right: 4px; - flex: 1 0 0; - white-space: nowrap; -} - -.plate-setup-clicked-button { - height: 23px; - font-family: "Roboto", Arial, sans-serif; - font-size: 12px; - border: none; - background-color: aquamarine; - border-radius: 2px; - margin-right: 4px; - flex: 1 0 0; - white-space: nowrap; -} - - -.plate-setup-canvas-container { - top: 52px; - left: 16px; - right: 16px; - bottom: 10px; - position: absolute; -} - -.plate-setup-tab-container { - position: absolute; - top:10px; - left:10px; - bottom: 10px; - right: 10px; - background-color: white; - border: solid 1px #e1e1e1; -} - -.plate-setup-tab-head { - left: 0; - right: 0; - height: 23px; - border-bottom: solid 1px #e1e1e1; - background-color: #f5f5f5; - display: flex; -} - -.plate-setup-tab { - height: 23px; - background-color: #ebebeb; - border-right: solid 1px #e1e1e1; - cursor: pointer; - font-family: "Roboto", Arial, sans-serif; - font-size: 10px; - text-align: center; - padding: 5px; - box-sizing: border-box; - flex: 1 1 auto; - white-space: nowrap; - overflow: hidden; -} - -.plate-setup-tab:last-child { - border-right: none; -} - -.plate-setup-tab-selected { - height: 24px; - background-color: white; - color: #00506e; - flex-shrink: 0; -} - -.plate-setup-tab-data-container { - left: 0; - right: 0; - height: 442px; - border-bottom: solid 1px #e1e1e1; - position: absolute; - font-family: "Roboto", Arial, sans-serif; -} - -.plate-setup-data-div { - top: 0; - left: 0; - bottom: 0; - right: 0; - position: absolute; - background-color: white; - overflow: auto; -} - -.plate-setup-well-attr-container { - top: 472px; - left: 0; - right: 0; - height: 20px; - box-sizing: border-box; - padding: 0px 16px; - color: #00506e; - text-align: center; - position: absolute; - font-size: 10px; - font-family: "Roboto", Arial, sans-serif; -} - -.plate-setup-preset-container { - top: 490px; - left: 0; - right: 0; - height: 22px; - position: absolute; - box-sizing: border-box; - padding: 0px 16px; - text-align: center; - display: flex; - justify-content: center; -} - -.plate-setup-prest-tab { - display: inline-block; - flex-basis: 50px; - padding: 0 5px; - margin: 0 1px; - height: 20px; - background-color: white; - border: solid 1px #e1e1e1; - border-radius: 2px; - cursor: pointer; - font-family: "Roboto", Arial, sans-serif; - font-size: 10px; - text-align: center; -} - -.plate-setup-prest-tab-selected { - display: inline-block; - flex-basis: 50px; - padding: 0 5px; - margin: 0 1px; - height: 20px; - background-color: #e1e1e1; - border: solid 1px #e1e1e1; - border-radius: 2px; - cursor: pointer; - font-family: "Roboto", Arial, sans-serif; - font-size: 11px; - text-align: center; - color: #00506e; -} - -.plate-setup-prest-tab-div { - padding-top: 3px; -} - -.plate-setup-tab-default-field { - display: flex; - padding: 10px 16px 0 16px; -} - -.plate-setup-tab-field-left-side { - width: 32px; - padding-top: 16px; -} - -.plate-setup-tab-field-right-side { - flex: 1; -} - -.plate-setup-tab-name { - font-family: "Roboto", Arial, sans-serif; - font-size: 12px; - display: inline-block; - line-height: 16px; -} - -.plate-setup-tab-name-singleSelect { - font-family: "Roboto", Arial, sans-serif; - font-size: 12px; - margin-top: 5px; -} - - -.plate-setup-tab-name-missing { - height: 20px; - font-family: "Roboto", Arial, sans-serif; - font-size: 12px; - background: red; -} - - -.plate-setup-tab-field-container, .plate-setup-tab-field-container-singleSelect { - width: 100%; - display: flex; -} - -.plate-setup-tab-input, .plate-setup-tab-select-field, .plate-setup-tab-multiplex-single-select-field { - height: 28px; - flex: 1 1 auto; - width: 30px; - margin: auto; -} - -.plate-setup-tab-multiselect-field { - min-height: 28px; - flex: 1 1 auto; - width: 30px; -} - -.plate-setup-tab-label-select-field, .plate-setup-tab-unit { - width: 130px; - overflow: hidden; - text-overflow: ellipsis; - height: 28px; - box-sizing: border-box; - padding-left: 5px; -} - -.plate-setup-tab-unit { - font-family: "Roboto", Arial, sans-serif; - line-height: 26px; - color: #444; - white-space: nowrap; -} - -.plate-setup-tab-check-box { - cursor: pointer; - border: 1px solid gray; - display: inline-block; - height: 16px; - width: 16px; - text-align: center; - line-height: 16px; -} - -.plate-setup-bottom-control-container { - top: 0; - left: 0; - right: 0; - height: 32px; - background-color: #464646; - position: absolute; - display: flex; - justify-content:space-between; - align-items: baseline; - vertical-align: middle; -} - -.plate-setup-bottom-container { - top: 540px; - left: 0; - right: 0; - bottom: 0; - position: absolute; - background-color: #e1e1e1; -} - -.plate-setup-bottom-table-container { - top: 32px; - left: 0; - bottom: 0; - right: 0; - position: absolute; - overflow: auto; -} - - -.plate-setup-bottom-table { - font-family: "Roboto", Arial, sans-serif; - font-size: 14px; - border-collapse: collapse; - width: 100%; -} - -.plate-setup-bottom-table th { - border: solid #c2c2c2 1px; - padding: 5px 10px; - font-weight: bold; - font-size: 12px; - text-align: left; -} - -.plate-setup-bottom-table td { - border: solid #c2c2c2 1px; - padding: 5px 10px; - background-color: white; -} - -.plate-setup-color-text { - font-size: 14px; - border: none; - border-radius: 2px; - padding: 3px 15px; - background-color: WHITE; - margin-right: 4px; -} - -.plate-setup-bottom-id { - width: 40px; - text-align: center; - background-image: linear-gradient(to right, rgba(255,255,255,0.3), transparent) -} - -input.invalid { - background-color: pink; -} - -.plate-setup-remove-all-button-container { - text-align: left; -} - -.plate-setup-remove-all-button{ - width: 100%; - font-family: "Roboto", Arial, sans-serif; - font-size: 12px; - text-overflow: ellipsis; - text-align: left; - white-space: nowrap; - border: 1px solid #aaa; - border-top: none; - color: #444; - background-color: #fff; - background-image: linear-gradient(to top, #eee 0%, #fff 50%); -} -/* Modal Content */ - -.modal { - display: none; /* Hidden by default */ - position: fixed; /* Stay in place */ - z-index: 2000; /* Sit on top */ - padding-top: 100px; /* Location of the box */ - left: 0; - top: 0; - width: 100%; /* Full width */ - height: 100%; /* Full height */ - overflow: auto; /* Enable scroll if needed */ - background-color: rgb(0,0,0); /* Fallback color */ - background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ -} - -.modal-content { - font-family: 'Roboto', sans-serif; - font-size: 14px; - background-color: #fefefe; - margin: auto; - padding: 20px; - border: 1px solid #888; -} - -.delete-dialog .modal-content { - width: 550px; -} - -.modal-content > * { - width: 100%; -} - -.dialog-buttons { - margin-top: 10px; - display: inline-block; - text-align: right; -} - -.dialog-buttons button { - margin-left: 4px; -} - -.plate-popout-table { - border-collapse: collapse; - width: 100%; - border: 1px solid black; - padding: 5px; -} - -.plate-popout-th { - text-align: left; - background-color: white; - color: black; - font-size: 12px; - border: 1px solid black; - padding: 5px; -} - -.plate-popout-tr:hover { - background-color: #f5f5f5; - border: 1px solid black; - padding: 5px; -} - -.plate-popout-td { - text-align: left; - font-size: 11px; - border: 1px solid black; - padding: 5px; -} - -.plate-field-warning-image{ - vertical-align: baseline; - margin: 0px 0 0px; -} - -.pop-out-text { - position: fixed; - display: none; - background: white; - border: 1px solid; - float: left; - margin-top: -44px; - z-Index: 99999 !important; -} diff --git a/dist/css/plate-map.min.css b/dist/css/plate-map.min.css deleted file mode 100644 index d7ff6e2..0000000 --- a/dist/css/plate-map.min.css +++ /dev/null @@ -1,2 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Roboto);.plate-setup-container{width:1024px;height:768px;position:relative;float:left}.plate-setup-wrapper{position:absolute;top:0;left:0;bottom:0;right:0;flex-direction:column;background-color:#f5f5f5}.plate-setup-top-section{height:540px;top:0;left:0;right:0;position:absolute}.plate-setup-top-left{width:674px;top:0;bottom:0;position:absolute}.plate-setup-top-right{left:674px;top:0;bottom:0;right:0;position:absolute}.plate-setup-overlay-container{height:32px;top:10px;left:16px;right:16px;position:inherit;background-color:#464646;border-radius:2px;display:flex;justify-content:space-between;align-items:baseline;vertical-align:middle}.plate-setup-overlay-radio-container{width:32px;height:32px}.plate-setup-overlay-text-container{color:#fff;font-size:12px;line-height:30px;height:32px;font-family:Roboto,Arial,sans-serif;margin:2px 8px;flex:1 1 auto}.plate-setup-overlay-bottom-button-container,.plate-setup-overlay-button-container{flex:0 0 auto;display:flex;flex:1 1 0}.plate-setup-button{height:23px;font-family:Roboto,Arial,sans-serif;font-size:12px;border:none;background-color:#fff;border-radius:2px;margin-right:4px;flex:1 0 0;white-space:nowrap}.plate-setup-clicked-button{height:23px;font-family:Roboto,Arial,sans-serif;font-size:12px;border:none;background-color:#7fffd4;border-radius:2px;margin-right:4px;flex:1 0 0;white-space:nowrap}.plate-setup-canvas-container{top:52px;left:16px;right:16px;bottom:10px;position:absolute}.plate-setup-tab-container{position:absolute;top:10px;left:10px;bottom:10px;right:10px;background-color:#fff;border:solid 1px #e1e1e1}.plate-setup-tab-head{left:0;right:0;height:23px;border-bottom:solid 1px #e1e1e1;background-color:#f5f5f5;display:flex}.plate-setup-tab{height:23px;background-color:#ebebeb;border-right:solid 1px #e1e1e1;cursor:pointer;font-family:Roboto,Arial,sans-serif;font-size:10px;text-align:center;padding:5px;box-sizing:border-box;flex:1 1 auto;white-space:nowrap;overflow:hidden}.plate-setup-tab:last-child{border-right:none}.plate-setup-tab-selected{height:24px;background-color:#fff;color:#00506e;flex-shrink:0}.plate-setup-tab-data-container{left:0;right:0;height:442px;border-bottom:solid 1px #e1e1e1;position:absolute;font-family:Roboto,Arial,sans-serif}.plate-setup-data-div{top:0;left:0;bottom:0;right:0;position:absolute;background-color:#fff;overflow:auto}.plate-setup-well-attr-container{top:472px;left:0;right:0;height:20px;box-sizing:border-box;padding:0 16px;color:#00506e;text-align:center;position:absolute;font-size:10px;font-family:Roboto,Arial,sans-serif}.plate-setup-preset-container{top:490px;left:0;right:0;height:22px;position:absolute;box-sizing:border-box;padding:0 16px;text-align:center;display:flex;justify-content:center}.plate-setup-prest-tab{display:inline-block;flex-basis:50px;padding:0 5px;margin:0 1px;height:20px;background-color:#fff;border:solid 1px #e1e1e1;border-radius:2px;cursor:pointer;font-family:Roboto,Arial,sans-serif;font-size:10px;text-align:center}.plate-setup-prest-tab-selected{display:inline-block;flex-basis:50px;padding:0 5px;margin:0 1px;height:20px;background-color:#e1e1e1;border:solid 1px #e1e1e1;border-radius:2px;cursor:pointer;font-family:Roboto,Arial,sans-serif;font-size:11px;text-align:center;color:#00506e}.plate-setup-prest-tab-div{padding-top:3px}.plate-setup-tab-default-field{display:flex;padding:10px 16px 0 16px}.plate-setup-tab-field-left-side{width:32px;padding-top:16px}.plate-setup-tab-field-right-side{flex:1}.plate-setup-tab-name{font-family:Roboto,Arial,sans-serif;font-size:12px;display:inline-block;line-height:16px}.plate-setup-tab-name-singleSelect{font-family:Roboto,Arial,sans-serif;font-size:12px;margin-top:5px}.plate-setup-tab-name-missing{height:20px;font-family:Roboto,Arial,sans-serif;font-size:12px;background:red}.plate-setup-tab-field-container,.plate-setup-tab-field-container-singleSelect{width:100%;display:flex}.plate-setup-tab-input,.plate-setup-tab-multiplex-single-select-field,.plate-setup-tab-select-field{height:28px;flex:1 1 auto;width:30px;margin:auto}.plate-setup-tab-multiselect-field{min-height:28px;flex:1 1 auto;width:30px}.plate-setup-tab-label-select-field,.plate-setup-tab-unit{width:130px;overflow:hidden;text-overflow:ellipsis;height:28px;box-sizing:border-box;padding-left:5px}.plate-setup-tab-unit{font-family:Roboto,Arial,sans-serif;line-height:26px;color:#444;white-space:nowrap}.plate-setup-tab-check-box{cursor:pointer;border:1px solid gray;display:inline-block;height:16px;width:16px;text-align:center;line-height:16px}.plate-setup-bottom-control-container{top:0;left:0;right:0;height:32px;background-color:#464646;position:absolute;display:flex;justify-content:space-between;align-items:baseline;vertical-align:middle}.plate-setup-bottom-container{top:540px;left:0;right:0;bottom:0;position:absolute;background-color:#e1e1e1}.plate-setup-bottom-table-container{top:32px;left:0;bottom:0;right:0;position:absolute;overflow:auto}.plate-setup-bottom-table{font-family:Roboto,Arial,sans-serif;font-size:14px;border-collapse:collapse;width:100%}.plate-setup-bottom-table th{border:solid #c2c2c2 1px;padding:5px 10px;font-weight:700;font-size:12px;text-align:left}.plate-setup-bottom-table td{border:solid #c2c2c2 1px;padding:5px 10px;background-color:#fff}.plate-setup-color-text{font-size:14px;border:none;border-radius:2px;padding:3px 15px;background-color:#fff;margin-right:4px}.plate-setup-bottom-id{width:40px;text-align:center;background-image:linear-gradient(to right,rgba(255,255,255,.3),transparent)}input.invalid{background-color:pink}.plate-setup-remove-all-button-container{text-align:left}.plate-setup-remove-all-button{width:100%;font-family:Roboto,Arial,sans-serif;font-size:12px;text-overflow:ellipsis;text-align:left;white-space:nowrap;border:1px solid #aaa;border-top:none;color:#444;background-color:#fff;background-image:linear-gradient(to top,#eee 0,#fff 50%)}.modal{display:none;position:fixed;z-index:2000;padding-top:100px;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:#000;background-color:rgba(0,0,0,.4)}.modal-content{font-family:Roboto,sans-serif;font-size:14px;background-color:#fefefe;margin:auto;padding:20px;border:1px solid #888}.delete-dialog .modal-content{width:550px}.modal-content>*{width:100%}.dialog-buttons{margin-top:10px;display:inline-block;text-align:right}.dialog-buttons button{margin-left:4px}.plate-popout-table{border-collapse:collapse;width:100%;border:1px solid #000;padding:5px}.plate-popout-th{text-align:left;background-color:#fff;color:#000;font-size:12px;border:1px solid #000;padding:5px}.plate-popout-tr:hover{background-color:#f5f5f5;border:1px solid #000;padding:5px}.plate-popout-td{text-align:left;font-size:11px;border:1px solid #000;padding:5px}.plate-field-warning-image{vertical-align:baseline;margin:0 0 0}.pop-out-text{position:fixed;display:none;background:#fff;border:1px solid;float:left;margin-top:-44px;z-Index:99999!important} -/*# sourceMappingURL=plate-map.min.css.map */ \ No newline at end of file diff --git a/dist/css/plate-map.min.css.map b/dist/css/plate-map.min.css.map deleted file mode 100644 index 1d3e613..0000000 --- a/dist/css/plate-map.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["plate-layout.css"],"names":[],"mappings":"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","file":"plate-map.min.css","sourcesContent":["@import url(http://fonts.googleapis.com/css?family=Roboto);\n\n.plate-setup-container {\n width: 1024px;\n height: 768px;\n position: relative;\n float: left;\n}\n\n.plate-setup-wrapper {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n flex-direction: column;\n background-color: #f5f5f5;\n}\n\n.plate-setup-top-section {\n height: 540px;\n top: 0;\n left: 0;\n right: 0;\n position: absolute;\n}\n\n.plate-setup-top-left {\n width: 674px;\n top: 0;\n bottom: 0;\n position: absolute;\n}\n\n.plate-setup-top-right {\n left: 674px;\n top: 0;\n bottom: 0;\n right: 0;\n position: absolute;\n}\n\n.plate-setup-overlay-container {\n height: 32px;\n top: 10px;\n left: 16px;\n right: 16px;\n position: inherit;\n background-color: #464646;\n border-radius: 2px;\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n vertical-align: middle;\n}\n\n.plate-setup-overlay-radio-container {\n width: 32px;\n height: 32px;\n}\n\n.plate-setup-overlay-text-container {\n color: white;\n font-size: 12px;\n line-height: 30px;\n height: 32px;\n font-family: \"Roboto\", Arial, sans-serif;\n margin: 2px 8px;\n flex: 1 1 auto;\n}\n\n.plate-setup-overlay-button-container, .plate-setup-overlay-bottom-button-container {\n flex: 0 0 auto;\n display: flex;\n flex: 1 1 0;\n}\n\n.plate-setup-button {\n height: 23px;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 12px;\n border: none;\n background-color: white;\n border-radius: 2px;\n margin-right: 4px;\n flex: 1 0 0;\n white-space: nowrap;\n}\n\n.plate-setup-clicked-button {\n height: 23px;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 12px;\n border: none;\n background-color: aquamarine;\n border-radius: 2px;\n margin-right: 4px;\n flex: 1 0 0;\n white-space: nowrap;\n}\n\n\n.plate-setup-canvas-container {\n top: 52px;\n left: 16px;\n right: 16px;\n bottom: 10px;\n position: absolute;\n}\n\n.plate-setup-tab-container {\n position: absolute;\n top:10px;\n left:10px;\n bottom: 10px;\n right: 10px;\n background-color: white;\n border: solid 1px #e1e1e1;\n}\n\n.plate-setup-tab-head {\n left: 0;\n right: 0;\n height: 23px;\n border-bottom: solid 1px #e1e1e1;\n background-color: #f5f5f5;\n display: flex;\n}\n\n.plate-setup-tab {\n height: 23px;\n background-color: #ebebeb;\n border-right: solid 1px #e1e1e1;\n cursor: pointer;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 10px;\n text-align: center;\n padding: 5px;\n box-sizing: border-box;\n flex: 1 1 auto;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.plate-setup-tab:last-child {\n border-right: none;\n}\n\n.plate-setup-tab-selected {\n height: 24px;\n background-color: white;\n color: #00506e;\n flex-shrink: 0;\n}\n\n.plate-setup-tab-data-container {\n left: 0;\n right: 0;\n height: 442px;\n border-bottom: solid 1px #e1e1e1;\n position: absolute;\n font-family: \"Roboto\", Arial, sans-serif;\n}\n\n.plate-setup-data-div {\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n position: absolute;\n background-color: white;\n overflow: auto;\n}\n\n.plate-setup-well-attr-container {\n top: 472px;\n left: 0;\n right: 0;\n height: 20px;\n box-sizing: border-box;\n padding: 0px 16px;\n color: #00506e;\n text-align: center;\n position: absolute;\n font-size: 10px;\n font-family: \"Roboto\", Arial, sans-serif;\n}\n\n.plate-setup-preset-container {\n top: 490px;\n left: 0;\n right: 0;\n height: 22px;\n position: absolute;\n box-sizing: border-box;\n padding: 0px 16px;\n text-align: center;\n display: flex;\n justify-content: center;\n}\n\n.plate-setup-prest-tab {\n display: inline-block;\n flex-basis: 50px;\n padding: 0 5px;\n margin: 0 1px;\n height: 20px;\n background-color: white;\n border: solid 1px #e1e1e1;\n border-radius: 2px;\n cursor: pointer;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 10px;\n text-align: center;\n}\n\n.plate-setup-prest-tab-selected {\n display: inline-block;\n flex-basis: 50px;\n padding: 0 5px;\n margin: 0 1px;\n height: 20px;\n background-color: #e1e1e1;\n border: solid 1px #e1e1e1;\n border-radius: 2px;\n cursor: pointer;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 11px;\n text-align: center;\n color: #00506e;\n}\n\n.plate-setup-prest-tab-div {\n padding-top: 3px;\n}\n\n.plate-setup-tab-default-field {\n display: flex;\n padding: 10px 16px 0 16px;\n}\n\n.plate-setup-tab-field-left-side {\n width: 32px;\n padding-top: 16px;\n}\n\n.plate-setup-tab-field-right-side {\n flex: 1;\n}\n\n.plate-setup-tab-name {\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 12px;\n display: inline-block;\n line-height: 16px;\n}\n\n.plate-setup-tab-name-singleSelect {\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 12px;\n margin-top: 5px;\n}\n\n\n.plate-setup-tab-name-missing {\n height: 20px;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 12px;\n background: red;\n}\n\n\n.plate-setup-tab-field-container, .plate-setup-tab-field-container-singleSelect {\n width: 100%;\n display: flex;\n}\n\n.plate-setup-tab-input, .plate-setup-tab-select-field, .plate-setup-tab-multiplex-single-select-field {\n height: 28px;\n flex: 1 1 auto;\n width: 30px;\n margin: auto;\n}\n\n.plate-setup-tab-multiselect-field {\n min-height: 28px;\n flex: 1 1 auto;\n width: 30px;\n}\n\n.plate-setup-tab-label-select-field, .plate-setup-tab-unit {\n width: 130px;\n overflow: hidden;\n text-overflow: ellipsis;\n height: 28px;\n box-sizing: border-box;\n padding-left: 5px;\n}\n\n.plate-setup-tab-unit {\n font-family: \"Roboto\", Arial, sans-serif;\n line-height: 26px;\n color: #444;\n white-space: nowrap;\n}\n\n.plate-setup-tab-check-box {\n cursor: pointer;\n border: 1px solid gray;\n display: inline-block;\n height: 16px;\n width: 16px;\n text-align: center;\n line-height: 16px;\n}\n\n.plate-setup-bottom-control-container {\n top: 0;\n left: 0;\n right: 0;\n height: 32px;\n background-color: #464646;\n position: absolute;\n display: flex;\n justify-content:space-between;\n align-items: baseline;\n vertical-align: middle;\n}\n\n.plate-setup-bottom-container {\n top: 540px;\n left: 0;\n right: 0;\n bottom: 0;\n position: absolute;\n background-color: #e1e1e1;\n}\n\n.plate-setup-bottom-table-container {\n top: 32px;\n left: 0;\n bottom: 0;\n right: 0;\n position: absolute;\n overflow: auto;\n}\n\n\n.plate-setup-bottom-table {\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 14px;\n border-collapse: collapse;\n width: 100%;\n}\n\n.plate-setup-bottom-table th {\n border: solid #c2c2c2 1px;\n padding: 5px 10px;\n font-weight: bold;\n font-size: 12px;\n text-align: left;\n}\n\n.plate-setup-bottom-table td {\n border: solid #c2c2c2 1px;\n padding: 5px 10px;\n background-color: white;\n}\n\n.plate-setup-color-text {\n font-size: 14px;\n border: none;\n border-radius: 2px;\n padding: 3px 15px;\n background-color: WHITE;\n margin-right: 4px;\n}\n\n.plate-setup-bottom-id {\n width: 40px;\n text-align: center;\n background-image: linear-gradient(to right, rgba(255,255,255,0.3), transparent)\n}\n\ninput.invalid {\n background-color: pink;\n}\n\n.plate-setup-remove-all-button-container {\n text-align: left;\n}\n\n.plate-setup-remove-all-button{\n width: 100%;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 12px;\n text-overflow: ellipsis;\n text-align: left;\n white-space: nowrap;\n border: 1px solid #aaa;\n border-top: none;\n color: #444;\n background-color: #fff;\n background-image: linear-gradient(to top, #eee 0%, #fff 50%);\n}\n/* Modal Content */\n\n.modal {\n display: none; /* Hidden by default */\n position: fixed; /* Stay in place */\n z-index: 2000; /* Sit on top */\n padding-top: 100px; /* Location of the box */\n left: 0;\n top: 0;\n width: 100%; /* Full width */\n height: 100%; /* Full height */\n overflow: auto; /* Enable scroll if needed */\n background-color: rgb(0,0,0); /* Fallback color */\n background-color: rgba(0,0,0,0.4); /* Black w/ opacity */\n}\n\n.modal-content {\n font-family: 'Roboto', sans-serif;\n font-size: 14px;\n background-color: #fefefe;\n margin: auto;\n padding: 20px;\n border: 1px solid #888;\n}\n\n.delete-dialog .modal-content {\n width: 550px;\n}\n\n.modal-content > * {\n width: 100%;\n}\n\n.dialog-buttons {\n margin-top: 10px;\n display: inline-block;\n text-align: right;\n}\n\n.dialog-buttons button {\n margin-left: 4px;\n}\n\n.plate-popout-table {\n border-collapse: collapse;\n width: 100%;\n border: 1px solid black;\n padding: 5px;\n}\n\n.plate-popout-th {\n text-align: left;\n background-color: white;\n color: black;\n font-size: 12px;\n border: 1px solid black;\n padding: 5px;\n}\n\n.plate-popout-tr:hover {\n background-color: #f5f5f5;\n border: 1px solid black;\n padding: 5px;\n}\n\n.plate-popout-td {\n text-align: left;\n font-size: 11px;\n border: 1px solid black;\n padding: 5px;\n}\n\n.plate-field-warning-image{\n vertical-align: baseline;\n margin: 0px 0 0px;\n}\n\n.pop-out-text {\n position: fixed;\n display: none;\n background: white;\n border: 1px solid;\n float: left;\n margin-top: -44px;\n z-Index: 99999 !important;\n}\n"]} \ No newline at end of file diff --git a/dist/js/plate-map.js b/dist/js/plate-map.js deleted file mode 100755 index 8ab5e1c..0000000 --- a/dist/js/plate-map.js +++ /dev/null @@ -1,4360 +0,0 @@ -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.addDataOnChange = function() { - // This object is invoked when something in the tab fields change - return { - - _addAllData: function(data) { - // Method to add data when something changes in the tabs. Its going to be tricky , just starting. - if (this.allSelectedObjects) { - var noOfSelectedObjects = this.allSelectedObjects.length; - var wells = []; - for (var objectIndex = 0; objectIndex < noOfSelectedObjects; objectIndex++) { - var tile = this.allSelectedObjects[objectIndex]; - var well; - if (tile.index in this.engine.derivative) { - well = this.engine.derivative[tile.index]; - } else { - well = $.extend(true, {}, this.defaultWell); - this.engine.derivative[tile.index] = well; - } - var processedData = this.processWellData(data, well, noOfSelectedObjects, wells); - wells = processedData.wells; - well = processedData.well; - var empty = this.engine.wellEmpty(well); - if (empty) { - if (this.emptyWellWithDefaultVal && this.disableAddDeleteWell) { - var wellCopy = JSON.parse(JSON.stringify(well)); - var defaultValue = this.emptyWellWithDefaultVal; - for (var key in defaultValue){ - if (key in wellCopy){ - wellCopy[key] = defaultValue[key]; - this._applyFieldData(key, defaultValue[key]); - } - } - this.engine.derivative[tile.index] = wellCopy; - } else { - delete this.engine.derivative[tile.index]; - } - } - } - } - // update multiplex remove all field - this._getAllMultipleVal(wells); - this.applyFieldWarning(wells); - // create well when default field is sent for the cases when user delete all fields during disabledNewDeleteWell mode - this._colorMixer(); - this.derivativeChange(); - }, - - processWellData: function(newData, curWell, noOfSelectedObjects, wellList) { - - if (!wellList){ - wellList = []; - } - for (var id in newData) { - var v; - if (newData[id] !== undefined && newData[id] !== null ) { - if (newData[id].multi){ - var curData = newData[id]; - var preData = curWell[id]; - var newDt = this._getMultiData(preData, curData, id, noOfSelectedObjects); - // need to replace newData - v = JSON.parse(JSON.stringify(newDt)); - } else { - v = JSON.parse(JSON.stringify(newData[id])); - } - } else { - v = JSON.parse(JSON.stringify(newData[id])); - } - curWell[id] = v; - wellList.push(curWell); - } - - return { - well: curWell, - wells: wellList - } - }, - - _getMultiData: function(preData, curData, fieldId, noOfSelectedObjects) { - var addNew = curData.added; - var removed = curData.removed; - if (addNew) { - if (preData){ - if (addNew.value) { - var add = true; - for (var listIdx in preData) { - var multiplexData = preData[listIdx]; - // for cases when the add new data exist in well - if (multiplexData[fieldId].toString() === addNew.id.toString()) { - add = false; - // update subfield value - preData = preData.map(function(val) { - if (val[fieldId].toString() === addNew.id.toString()) { - for (var subFieldId in val) { - // over write previous data if only one well is selected - if (subFieldId in addNew.value && subFieldId !== fieldId){ - if (noOfSelectedObjects === 1) { - val[subFieldId] = addNew.value[subFieldId]; - } else if (addNew.value[subFieldId]) { - val[subFieldId] = addNew.value[subFieldId]; - } - } - } - } - return val; - }) - } - } - if (add) { - preData.push(addNew.value); - } - } else if (preData.indexOf(addNew) < 0) { - preData.push(addNew); - } - } else { - preData = []; - if (addNew.value) { - preData.push(addNew.value); - } else if (addNew){ - preData.push(addNew); - } - } - } - - var removeListIndex = function(preData, removeIndex) { - var newPreData = []; - for (var idx in preData) { - if (parseInt(idx) !== parseInt(removeIndex)){ - newPreData.push(preData[idx]); - } - } - return newPreData; - }; - - if (removed) { - var removeIndex; - // for multiplex field - if (removed.value) { - for (var listIdx in preData) { - var multiplexData = preData[listIdx]; - if (multiplexData[fieldId].toString() === removed.id.toString()) { - removeIndex = listIdx; - } - } - // remove nested element - preData = removeListIndex(preData, removeIndex); - } else { - if (preData){ - removeIndex = preData.indexOf(removed); - if (removeIndex >= 0) { - preData = removeListIndex(preData, removeIndex); - } - } - } - } - if (preData && (preData.length == 0)) { - preData = null; - } - return preData - }, - - _colorMixer: function() { - if (!this.undoRedoActive) { - var data = this.createObject(); - this.addToUndoRedo(data); - } - this.engine.searchAndStack(); - this.engine.applyColors(); - this.mainFabricCanvas.renderAll(); - }, - - derivativeChange: function(){ - this._trigger("updateWells", null, this.createObject()); - }, - - createObject: function() { - var derivative = $.extend(true, {}, this.engine.derivative); - var checkboxes = this.globalSelectedAttributes.slice(); - var selectedAreas = this.selectedAreas.slice(); - var focalWell = this.focalWell; - - return { - "derivative": derivative, - "checkboxes": checkboxes, - "selectedAreas": selectedAreas, - "focalWell": focalWell, - "requiredField": this.requiredField - }; - } - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.addDataToFields = function() { - - return { - - _addDataToTabFields: function(values) { - // Configure how data is added to tab fields - for (var id in values) { - this._applyFieldData(id, values[id]); - } - }, - - _applyFieldData: function(id, v) { - this.fieldMap[id].setValue(v); - } - } - } -})(jQuery, fabric) -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.addTabData = function() { - - return { - - fieldList: [], - fieldMap: {}, - autoId: 1, - - _addTabData: function() { - // Here we may need more changes because attributes format likely to change - var tabData = this.options.attributes.tabs; - var that = this; - this.requiredField = []; - var multiplexFieldArray = []; - tabData.forEach(function (tab, tabPointer) { - if (tab["fields"]) { - var tabFields = tab["fields"]; - var fieldArray = []; - var fieldArrayIndex = 0; - // Now we look for fields in the json - for (var field in tabFields) { - var data = tabFields[field]; - - if (!data.id) { - data.id = "Auto" + that.autoId++; - console.log("Field autoassigned id " + data.id); - } - if (!data.type) { - data.type = "text"; - console.log("Field " + data.id + " autoassigned type " + data.type); - } - - var field_val; - if (data.type === "multiplex") { - field_val = that._makeMultiplexField(data, tabPointer, fieldArray); - multiplexFieldArray.push(field_val); - } else { - field_val = that._makeRegularField(data, tabPointer, fieldArray, true); - if (data.type === "multiselect") { - multiplexFieldArray.push(field_val); - } - }; - } - - that.allDataTabs[tabPointer]["fields"] = fieldArray; - } else { - console.log("unknown format in field initialization"); - } - }); - that.multipleFieldList = multiplexFieldArray; - }, - - _makeSubField: function (data, tabPointer, fieldArray) { - var that = this; - if (!data.id) { - data.id = "Auto" + that.autoId++; - console.log("Field autoassigned id " + data.id); - } - if (!data.type) { - data.type = "text"; - console.log("Field " + data.id + " autoassigned type " + data.type); - } - var wrapperDiv = that._createElement("<div></div>").addClass("plate-setup-tab-default-field"); - var wrapperDivLeftSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"); - var wrapperDivRightSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-right-side"); - var nameContainer = that._createElement("<div></div>").addClass("plate-setup-tab-name").text(data.name); - var fieldContainer = that._createElement("<div></div>").addClass("plate-setup-tab-field-container"); - - $(wrapperDivRightSide).append(nameContainer); - $(wrapperDivRightSide).append(fieldContainer); - $(wrapperDiv).append(wrapperDivLeftSide); - $(wrapperDiv).append(wrapperDivRightSide); - $(that.allDataTabs[tabPointer]).append(wrapperDiv); - - var field = { - id: data.id, - name: data.name, - root: wrapperDiv, - data: data, - required: data.required || false - }; - - fieldArray.push(field); - that.fieldMap[data.id] = field; - - return field; - }, - - _makeRegularField: function (data, tabPointer, fieldArray, checkbox){ - var that = this; - var wrapperDiv = that._createElement("<div></div>").addClass("plate-setup-tab-default-field"); - var wrapperDivLeftSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"); - var wrapperDivRightSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-right-side "); - var nameContainer = that._createElement("<div></div>").addClass("plate-setup-tab-name").text(data.name); - var fieldContainer = that._createElement("<div></div>").addClass("plate-setup-tab-field-container"); - - wrapperDivRightSide.append(nameContainer); - wrapperDivRightSide.append(fieldContainer); - wrapperDiv.append(wrapperDivLeftSide); - wrapperDiv.append(wrapperDivRightSide); - that.allDataTabs[tabPointer].append(wrapperDiv); - - var field = { - id: data.id, - name: data.name, - root: wrapperDiv, - data: data, - required: data.required - }; - - if (field.required) { - that.requiredField.push(field.id); - } - - fieldArray.push(field); - that.fieldList.push(field); - that.fieldMap[field.id] = field; - - // Adding checkbox - if (checkbox) { - that._addCheckBox(field); - } - that._createField(field); - - field.onChange = function () { - var v = field.getValue(); - var data = {}; - data[field.id] = v; - that._addAllData(data); - }; - return field; - }, - - _makeMultiplexField: function (data, tabPointer, fieldArray) { - var that = this; - var wrapperDiv = that._createElement("<div></div>").addClass("plate-setup-tab-default-field"); - var wrapperDivLeftSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"); - var wrapperDivRightSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-right-side "); - var nameContainer = that._createElement("<div></div>").addClass("plate-setup-tab-name").text(data.name); - var fieldContainer = that._createElement("<div></div>").addClass("plate-setup-tab-field-container"); - - wrapperDivRightSide.append(nameContainer); - wrapperDivRightSide.append(fieldContainer); - wrapperDiv.append(wrapperDivLeftSide); - wrapperDiv.append(wrapperDivRightSide); - that.allDataTabs[tabPointer].append(wrapperDiv); - - var field = { - id: data.id, - name: data.name, - root: wrapperDiv, - data: data, - required: data.required - }; - - fieldArray.push(field); - that.fieldList.push(field); - that.fieldMap[data.id] = field; - - var subFieldList = []; - //create subfields - var requiredSubField = []; - for (var subFieldKey in data.multiplexFields) { - var subFieldData = data.multiplexFields[subFieldKey]; - var subField = that._makeSubField(subFieldData, tabPointer, fieldArray); - subFieldList.push(subField); - - // stores required subField - if (subFieldData.required) { - requiredSubField.push(subField.id); - } - } - - //store required field - if (field.required || requiredSubField.length) { - this.requiredField.push ({ - multiplexId: field.id, - subFields: requiredSubField - }); - } - - field.subFieldList = subFieldList; - that._createField(field); - that._addCheckBox(field); - - subFieldList.forEach(function (subfield) { - subfield.mainMultiplexField = field; - fieldArray.push(subfield); - that._createField(subfield); - that._addCheckBox(subfield); - delete that.defaultWell[subfield.id]; - // overwrite subField setvalue - subfield.onChange = function () { - var v = subfield.getValue(); - var mainRefField = subfield.mainMultiplexField; - var curId = mainRefField.singleSelectValue(); - //var curDataLs = mainRefField.detailData; - var curVal = {}; - curVal[mainRefField.id] = curId; - //append subfields - curVal[subfield.id] = v; - var returnVal = { - id: curId, - value: curVal - }; - - field._changeMultiFieldValue(returnVal, null); - var curDataLs = mainRefField.detailData; - if (curDataLs !== null) { - curId = mainRefField.singleSelectValue(); - curDataLs = curDataLs.map(function(curData) { - if (curData[mainRefField.id] === curId) { - curData[subfield.id] = v; - } - return curData; - }); - } - mainRefField.detailData = curDataLs; - }; - - }); - - field.getValue = function(){ - var v = field.input.select2('data'); - if (v.length) { - return v.map(function (i) { - return i.id; - }); - } - return null; - }; - - return field; - } - } - } - -})(jQuery, fabric); - -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.addWarningMsg = function () { - // For those check boxes associated with every field in the tab - return { - fieldWarningMsg: function (field, text, include) { - var that = this; - var imgId = "fieldWarning" + field.id; - var img = $("<span>").html(that._assets.warningImg).attr("id", imgId).addClass("plate-field-warning-image"); - //field.root.find(".plate-setup-tab-name").append('<img id="theImg" src="theImg.png" />') - if (include) { - if (field.root.find("#" + imgId).length <= 0){ - field.root.find(".plate-setup-tab-name").text(" " + field.name); - field.root.find(".plate-setup-tab-name").prepend(img); - - var popText = $("<div/>").addClass("pop-out-text"); - popText.text(text); - field.root.find(".plate-setup-tab-name").append(popText); - - $("#" + imgId).hover(function (e) { - popText[0].style.display = 'flex'; - }, function () { - popText.hide(); - }); - } - - - } else { - if (field.root.find("#" + imgId).length > 0) { - field.root.find(".plate-setup-tab-name").text(field.name); - $("#" + imgId).remove(); - } - } - }, - - removeWarningMsg: function (field, text, include) { - var that = this; - var imgId = "fieldWarning" + field.id; - var img = $("<span>").html(that._assets.warningImg).attr("id", imgId).addClass("plate-field-warning-image"); - //field.root.find(".plate-setup-tab-name").append('<img id="theImg" src="theImg.png" />') - if (include) { - field.root.find(".plate-setup-tab-name").append(img); - - var popText = $("<div/>").addClass("pop-out-text"); - popText.text(text); - field.root.find(".plate-setup-tab-name").append(popText); - - $("#" + imgId).hover(function (e) { - popText[0].style.display = 'inline-block'; - }, function () { - popText.hide(); - }); - - } else { - $("#" + imgId).remove(); - if (field.root.find("#" + imgId).length > 0) { - //field.root.find(".plate-setup-tab-name").remove(img); - $("#" + imgId).remove(); - } - } - }, - - applyFieldWarning: function(wells) { - var that = this; - var req = 0; - var fill = 0; - var fieldData = {}; - that.fieldList.forEach(function(field){ - fieldData[field.id] = []; - }); - wells.forEach(function(well){ - if (!that.engine.wellEmpty(well)){ - for (var fieldId in fieldData) { - if (fieldId in well) { - fieldData[fieldId].push(well[fieldId]); - } else { - fieldData[fieldId].push(null); - } - } - } - }); - for (var i = 0; i < that.fieldList.length; i++) { - var field = that.fieldList[i]; - if (field.applyMultiplexSubFieldColor){ - field.applyMultiplexSubFieldColor(fieldData[field.id]); - } else { - if (field.required) { - var include = false; - fieldData[field.id].forEach(function(val){ - // for multiselect - if (val instanceof Array) { - if (val.length === 0) { - include = true; - } - } else { - if (val === null) { - include = true; - } - } - }); - //field.root.find(".plate-setup-tab-name").css("background", color); - that.fieldWarningMsg(field, "required field", include); - } - } - } - } - } - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.bottomTable = function() { - // for bottom table - return { - _bottomScreen: function() { - this.bottomContainer = this._createElement("<div></div>").addClass("plate-setup-bottom-container"); - this.bottomTableContainer = this._createElement("<div></div>").addClass("plate-setup-bottom-table-container"); - this.bottomTable = this._createElement("<table></table>").addClass("plate-setup-bottom-table"); - this.bottomTableContainer.append(this.bottomTable); - this.bottomContainer.append(this.bottomTableContainer); - this.container.append(this.bottomContainer); - }, - - addBottomTableHeadings: function() { - - this.bottomRow = this._createElement("<tr></tr>"); - - var singleField = this._createElement("<th></th>") - .text("Group"); - this.bottomRow.prepend(singleField); - // Now we append all the captions at the place. - this.bottomTable.empty(); - this.bottomTable.append(this.bottomRow); - - this.rowCounter = 1; - - for (var i = 0; i < this.globalSelectedAttributes.length; i++) { - var attr = this.globalSelectedAttributes[i]; - var field = this.fieldMap[attr]; - var singleField = this._createElement("<th></th>").text(field.name); - this.bottomRow.append(singleField); - this.rowCounter = this.rowCounter + 1; - } - - this.adjustFieldWidth(this.bottomRow); - }, - - tileAttrText: function(tile, attr) { - var well = this.engine.derivative[tile.index]; - var field = this.fieldMap[attr]; - return field.getText(well[attr]); - }, - - addBottomTableRow: function(color, singleStack) { - var that = this; - var modelTile = this.allTiles[singleStack[0]]; - var row = this._createElement("<tr></tr>"); - var plateIdDiv = this._createElement("<td></td>").addClass("plate-setup-bottom-id"); - var numberText = this._createElement("<button/>"); - numberText.addClass("plate-setup-color-text"); - numberText.text(color); - plateIdDiv.append(numberText); - - numberText.click(function(evt){ - var addressToSelect = singleStack.map(function(addressIdx){ - return that.indexToAddress(addressIdx) - }); - if (evt.ctrlKey) { - that.getSelectedAddress().forEach(function(val){ - if (addressToSelect.indexOf(val) < 0){ - addressToSelect.push(val); - } - }) - } - that.setSelectedWell(addressToSelect); - that._trigger("selectedWells", null, {selectedAddress: that.getSelectedAddress()}); - }); - - if (color > 0) { - color = ((color - 1) % (this.colorPairs.length - 1)) + 1; - } - var colorStops = this.colorPairs[color]; - - plateIdDiv.css("background", "linear-gradient(to right, " + colorStops[0] + " , " + colorStops[1] + ")"); - - row.append(plateIdDiv); - - for (var i = 0; i < this.globalSelectedAttributes.length; i++) { - var attr = this.globalSelectedAttributes[i]; - var text = this.tileAttrText(modelTile, attr); - var dataDiv = this._createElement("<td></td>").text(text); - row.append(dataDiv); - } - this.bottomTable.append(row); - this.adjustFieldWidth(row); - }, - - bottomForFirstTime: function() { - this.addBottomTableHeadings(); - // This is executed for the very first time.. ! - var row = this._createElement("<tr></tr>"); - - var colorStops = this.colorPairs[0]; - var plateIdDiv = this._createElement("<td></td>"); - plateIdDiv.css("background", "-webkit-linear-gradient(left, " + colorStops[0] + " , " + colorStops[1] + ")"); - row.append(plateIdDiv); - this.bottomTable.append(row); - this.createExportButton(); - }, - - adjustFieldWidth: function(row) { - - var length = this.rowCounter; - if ((length) * 150 > 1024) { - row.css("width", (length) * 152 + "px"); - } - }, - - downloadCSV: function(csv, filename) { - var csvFile; - var downloadLink; - - // CSV file - csvFile = new Blob([csv], { - type: "text/csv" - }); - - // Download link - downloadLink = document.createElement("a"); - - // File name - downloadLink.download = filename; - - // Create a link to the file - downloadLink.href = window.URL.createObjectURL(csvFile); - - // Hide download link - downloadLink.style.display = "none"; - - // Add the link to DOM - document.body.appendChild(downloadLink); - - // Click download link - downloadLink.click(); - }, - - exportData: function(format) { - var data = []; - var rows = document.querySelectorAll("table tr"); - - var colorLocMap = {}; - var colorLocIdxMap = this.engine.stackUpWithColor; - var dim = this.getDimensions(); - var that = this; - for (var colorIdx in colorLocIdxMap) { - colorLocMap[colorIdx] = colorLocIdxMap[colorIdx].map(function (locIdx) { - return that.indexToAddress(locIdx, dim); - }) - } - - for (var i = 0; i < rows.length; i++) { - var row = [], - cols = rows[i].querySelectorAll("td, th"); - - for (var j = 0; j < cols.length; j++) { - var v = ""; - if (cols[j].innerText) { - if (format === "csv") { - v = '"' + cols[j].innerText.replace(/"/g, '""') + '"'; - } else { - v = cols[j].innerText; - } - } - row.push(v); - - // add location column - if (i === 0 && j === 0) { - if (format === "csv") { - row.push('"Location"'); - } else if (format === 'clipboard') { - row.push("Location"); - } - - } - if (i !== 0 && j === 0) { - var loc = ''; - if (colorLocMap[parseInt(cols[j].innerText)]) { - if (format === "csv") { - loc = '"' + colorLocMap[parseInt(cols[j].innerText)].join(",") + '"'; - } else if (format === 'clipboard') { - loc = colorLocMap[parseInt(cols[j].innerText)].join(","); - } - } - row.push(loc); - } - } - - if (format === "csv") { - data.push(row.join(",")); - } else if (format === 'clipboard') { - data.push(row.join("\t")); - //data.push(row); // for text type - } - - } - if (format === "csv") { - // Download CSV file - this.downloadCSV(data.join("\n"), 'table.csv'); - } else if (format === 'clipboard') { - //return formatTableToString(data); // for text type - return data.join("\n"); - } - }, - - createExportButton: function() { - var that = this; - var overlayContainer = $("<div>").addClass("plate-setup-bottom-control-container"); - - var descriptionDiv = $("<div>").addClass("plate-setup-overlay-text-container"); - descriptionDiv.text("Color groups"); - overlayContainer.append(descriptionDiv); - - var buttonContainer = $("<div>").addClass("plate-setup-overlay-bottom-button-container"); - - // create export csv option - var exportButton = $("<button/>").addClass("plate-setup-button"); - exportButton.text("Export CSV"); - buttonContainer.append(exportButton); - - exportButton.click(function() { - that.exportData('csv'); - exportButton.text("Exported"); - exportButton[0].classList.remove("plate-setup-button"); - exportButton.addClass("plate-setup-clicked-button"); - setTimeout(resetExportText, 3000); - }); - - function resetExportText() { - exportButton.text("Export CSV"); - exportButton[0].classList.remove("plate-setup-clicked-button"); - exportButton.addClass("plate-setup-button"); - } - - // creat clipboard option, CLipboard is an external js file located in vendor/asset/javascripts - var clipboardButton = $("<button/>").addClass("plate-setup-button"); - clipboardButton.text("Copy To Clipboard"); - buttonContainer.append(clipboardButton); - - var clipboard = new ClipboardJS(clipboardButton.get(0), { - text: function() { - return that.exportData("clipboard"); - } - }); - - clipboard.on('success', function(e) { - clipboardButton.text("Copied as tab-delimited format"); - clipboardButton[0].classList.remove("plate-setup-button"); - clipboardButton.addClass("plate-setup-clicked-button"); - setTimeout(resetClipboardText, 3000); - }); - - function resetClipboardText() { - clipboardButton.text("Copy To Clipboard"); - clipboardButton[0].classList.remove("plate-setup-clicked-button"); - clipboardButton.addClass("plate-setup-button"); - } - - clipboard.on('error', function(e) { - clipboardButton.text("Failed to copy table to clipboard: browser may be incompatible"); - setTimeout(resetClipboardText, 3000); - }); - - overlayContainer.append(buttonContainer); - $(".plate-setup-bottom-container").prepend(overlayContainer); - } - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.canvas = function() { - // - return { - - allSelectedObjects: null, // Contains all the selected objets, when click and drag. - - allPreviouslySelectedObjects: null, - - colorPointer: 0, - - goldenRatio: 0.618033988749895, - - _createCanvas: function() { - this.normalCanvas = this._createElement("<canvas>").attr("id", "DNAcanvas"); - $(this.canvasContainer).append(this.normalCanvas); - }, - - _initiateFabricCanvas: function() { - var w = this.canvasContainer.width(); - var h = this.canvasContainer.height(); - - this._setCanvasArea(w, h); - - this.mainFabricCanvas = new fabric.Canvas('DNAcanvas', { - backgroundColor: '#f5f5f5', - selection: false, - stateful: false, - hoverCursor: "pointer", - renderOnAddRemove: false, - }) - .setWidth(w) - .setHeight(h); - }, - - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.checkBox = function() { - // For those check boxes associated with every field in the tab - return { - - globalSelectedAttributes: [], - - _addCheckBox: function(field) { - var checkImage = $("<span>").html(this._assets.dontImg).addClass("plate-setup-tab-check-box bg-light") - .data("clicked", false); - checkImage.data("linkedFieldId", field.id); - field.root.find(".plate-setup-tab-field-left-side").empty().append(checkImage); - this._applyCheckboxHandler(checkImage); // Adding handler for change the image when clicked - field.checkbox = checkImage; - }, - - _applyCheckboxHandler: function(checkBoxImage) { - // We add checkbox handler here, thing is it s not checkbox , its an image and we change - // source - var that = this; - checkBoxImage.click(function(evt, machineClick) { - var checkBox = $(this); - - var changes = {}; - changes[checkBox.data("linkedFieldId")] = !checkBox.data("clicked"); - - that.changeCheckboxes(changes); - }); - }, - - changeSubFieldsCheckboxes: function(field, changes) { - var that = this; - var subFieldToInclude = []; - - field.subFieldList.forEach(function(subField) { - var checkImage = subField.checkbox; - var fieldId = checkImage.data("linkedFieldId"); - var clicked = checkImage.data("clicked"); - if (fieldId in changes) { - clicked = Boolean(changes[fieldId]); - } - checkImage.data("clicked", clicked); - if (clicked) { - checkImage.html(that._assets.doImg); - subFieldToInclude.push(subField.id); - } else { - checkImage.html(that._assets.dontImg); - } - }); - return subFieldToInclude; - }, - - changeCheckboxes: function(changes) { - var gsa = []; - var multiplexCheckedSubField = {}; - for (var i = 0; i < this.fieldList.length; i++) { - var field = this.fieldList[i]; - if (field.checkbox) { - if (field.subFieldList) { - multiplexCheckedSubField[field.id] = this.changeSubFieldsCheckboxes(field, changes); - } - - var checkImage = field.checkbox; - var fieldId = checkImage.data("linkedFieldId"); - var clicked = checkImage.data("clicked"); - if (fieldId in changes) { - clicked = Boolean(changes[fieldId]); - } - checkImage.data("clicked", clicked); - if (clicked) { - gsa.push(fieldId); - checkImage.html(this._assets.doImg); - } else { - checkImage.html(this._assets.dontImg); - } - } - } - this.globalSelectedMultiplexSubfield = multiplexCheckedSubField; - this.globalSelectedAttributes = gsa; - this._clearPresetSelection(); - this._colorMixer(); - }, - - setSubFieldCheckboxes: function(field, fieldIds) { - var that = this; - var subFieldToInclude = []; - field.subFieldList.forEach(function(subField) { - var checkImage = subField.checkbox; - var fieldId = checkImage.data("linkedFieldId"); - var clicked = fieldIds.indexOf(fieldId) >= 0; - checkImage.data("clicked", clicked); - if (clicked) { - checkImage.html(that._assets.doImg); - subFieldToInclude.push(subField.id); - } else { - checkImage.html(that._assets.dontImg); - } - }); - return subFieldToInclude; - }, - - setCheckboxes: function(fieldIds) { - fieldIds = fieldIds || []; - var gsa = []; - var multiplexCheckedSubField = {}; - - for (var i = 0; i < this.fieldList.length; i++) { - var field = this.fieldList[i]; - if (field.checkbox) { - // special handling for multiplex field - if (field.subFieldList) { - multiplexCheckedSubField[field.id] = this.setSubFieldCheckboxes(field, fieldIds); - } - - var checkImage = field.checkbox; - var fieldId = checkImage.data("linkedFieldId"); - var clicked = fieldIds.indexOf(fieldId) >= 0; - checkImage.data("clicked", clicked); - if (clicked) { - gsa.push(fieldId); - checkImage.html(this._assets.doImg); - } else { - - checkImage.html(this._assets.dontImg); - } - } - } - this.globalSelectedMultiplexSubfield = multiplexCheckedSubField; - this.globalSelectedAttributes = gsa; - this._clearPresetSelection(); - this._colorMixer(); - } - - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.colorManager = function() { - - return { - // See these are color pairs for the gradient. - colorPairs: [ - ["#e6e6e6", "#808080"], - ["#66e8ff", "#0082c8"], - ["#ff7fb1", "#e6194b"], - ["#a2ffb1", "#3cb44b"], - ["#f784ff", "#911eb4"], - ["#ffe897", "#f58231"], - ["#6666ff", "#0000FF"], - ["#ffff7f", "#ffe119"], - ["#acffff", "#46f0f0"], - ["#ff98ff", "#f032e6"], - ["#ffffa2", "#d2f53c"], - ["#ffffff", "#fabebe"], - ["#66e6e6", "#008080"], - ["#ffffff", "#e6beff"], - ["#ffd48e", "#aa6e28"], - ["#e66666", "#800000"], - ["#ffffff", "#aaffc3"], - ["#e6e666", "#808000"], - ["#ffffff", "#ffd8b1"], - ["#66a9ef", "#004389"], - ["#ff6672", "#a7000c"], - ["#66db72", "#00750c"], - ["#b866db", "#520075"], - ["#ffa966", "#b64300"], - ["#ffff66", "#c0a200"], - ["#6dffff", "#07b1b1"], - ["#ff66ff", "#b100a7"], - ["#f9ff66", "#93b600"], - ["#ffe5e5", "#bb7f7f"], - ["#66a7a7", "#004141"], - ["#ffe5ff", "#a77fc0"], - ["#d19566", "#6b2f00"], - ["#ffffef", "#c0bb89"], - ["#d1ffea", "#6bc084"], - ["#a7a766", "#414100"], - ["#ffffd8", "#c09972"], - ["#a5ffff", "#3fc1ff"], - ["#ffbef0", "#ff588a"], - ["#e1fff0", "#7bf38a"], - ["#ffc3ff", "#d05df3"], - ["#ffffd6", "#ffc170"], - ["#a5a5ff", "#3f3fff"], - ["#ffffbe", "#ffff58"], - ["#ebffff", "#85ffff"], - ["#ffd7ff", "#ff71ff"], - ["#a5ffff", "#3fbfbf"], - ["#ffffcd", "#e9ad67"], - ["#ffa5a5", "#bf3f3f"], - ["#ffffa5", "#bfbf3f"] - ] - } - } - -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.createCanvasElements = function() { - // this class manages creating all the elements within canvas - return { - - scaleFactor: 1, - - baseSizes: { - spacing: 48, - tile_radius: 22, - center_radius_complete: 10, - center_radius_incomplete: 14, - label_size: 14, - label_spacing: 24, - text_size: 13, - stroke: 0.5, - gap: 2 - }, - - _setCanvasArea: function(w, h) { - this.scaleFactor = Math.min( - h / (this.dimensions.rows * this.baseSizes.spacing + this.baseSizes.label_spacing), - w / (this.dimensions.cols * this.baseSizes.spacing + this.baseSizes.label_spacing)); - - var sizes = {} - for (var prop in this.baseSizes) { - sizes[prop] = this.baseSizes[prop] * this.scaleFactor; - } - this.sizes = sizes; - }, - - _canvas: function() { - // Those 1,2,3 s and A,B,C s - this._fixRowAndColumn(); - - // All those circles in the canvas. - this._putCircles(); - }, - - _fixRowAndColumn: function() { - var cols = this.dimensions.cols; - var rows = this.dimensions.rows; - - var spacing = this.sizes.spacing; - var d1 = this.sizes.label_spacing / 2; - var d2 = this.sizes.label_spacing + this.sizes.spacing / 2; - var fontSize = this.sizes.label_size; - - // For column - var top = d1; - var left = d2; - for (var i = 1; i <= cols; i++) { - var tempFabricText = new fabric.IText(i.toString(), { - fill: 'black', - originX: 'center', - originY: 'center', - fontSize: fontSize, - top: top, - left: left, - fontFamily: '"Roboto", Arial, sans-serif', - selectable: false, - fontWeight: "400" - }); - left += spacing; - - this.mainFabricCanvas.add(tempFabricText); - } - - // for row - top = d2; - left = d1; - for (var i = 1; i <= rows; i++) { - var tempFabricText = new fabric.IText(this.rowIndex[i-1], { - fill: 'black', - originX: 'center', - originY: 'center', - fontSize: fontSize, - top: top, - left: left, - fontFamily: '"Roboto", Arial, sans-serif', - selectable: false, - fontWeight: "400" - }); - top += spacing; - - this.mainFabricCanvas.add(tempFabricText); - } - }, - - _putCircles: function() { - var cols = this.dimensions.cols; - var rows = this.dimensions.rows; - - var tileCounter = 0; - for (var row = 0; row < rows; row++) { - for (var col = 0; col < cols; col++) { - var index = this.allTiles.length; - var tile = this._createTile(row, col); - tile.index = tileCounter++; - this.allTiles.push(tile); - this.mainFabricCanvas.add(tile.background); - this.mainFabricCanvas.add(tile.highlight); - this.mainFabricCanvas.add(tile.circle); - this.mainFabricCanvas.add(tile.circleCenter); - this.mainFabricCanvas.add(tile.circleText); - } - } - - this._addLargeRectangleOverlay(); - this._fabricEvents(); - }, - - _createTile: function (row, col) { - var tile = {}; - - tile.visible = false; - tile.colorIndex = null; - tile.row = row; - tile.col = col; - tile.address = this.rowIndex[row] + (col + 1); - - var top = (row + 1) * this.sizes.spacing; - var left = (col + 1) * this.sizes.spacing; - - tile.background = new fabric.Circle({ - top: top, - left: left, - radius: this.sizes.tile_radius, - originX: 'center', - originY: 'center', - hasControls: false, - hasBorders: false, - lockMovementX: true, - lockMovementY: true, - evented: false, - }); - - tile.background.setGradient("fill", { - type: "radial", - x1: this.sizes.tile_radius, - x2: this.sizes.tile_radius, - y1: this.sizes.tile_radius + this.sizes.gap, - y2: this.sizes.tile_radius + this.sizes.gap, - r1: this.sizes.tile_radius - this.sizes.gap, - r2: this.sizes.tile_radius, - colorStops: { - 0: 'rgba(0,0,0,0.1)', - 1: 'rgba(0,0,0,0.2)' - } - }); - - tile.highlight = new fabric.Rect({ - originX: 'center', - originY: 'center', - top: top, - left: left, - width: this.sizes.spacing, - height: this.sizes.spacing, - fill: "rgba(0,0,0,0.4)", - evented: false, - visible: false - }); - - tile.circle = new fabric.Circle({ - originX: 'center', - originY: 'center', - top: top, - left: left, - radius: this.sizes.tile_radius, - stroke: 'gray', - strokeWidth: this.sizes.stroke, - evented: false, - visible: false - }); - - tile.circleCenter = new fabric.Circle({ - originX: 'center', - originY: 'center', - top: top, - left: left, - radius: this.sizes.center_radius_incomplete, - fill: "white", - stroke: 'gray', - strokeWidth: this.sizes.stroke, - evented: false, - visible: false - }); - - tile.circleText = new fabric.IText("", { - originX: 'center', - originY: 'center', - top: top, - left: left, - fill: 'black', - fontFamily: '"Roboto", Arial, sans-serif', - fontSize: this.sizes.text_size, - lockScalingX: true, - lockScalingY: true, - evented: false, - visible: false - }); - - return tile; - }, - - setTileComplete: function (tile, complete) { - if (complete) { - tile.circleCenter.radius = this.sizes.center_radius_complete; - tile.circleText.fill = "black"; - tile.circleText.fontWeight = 'normal'; - } else { - tile.circleCenter.radius = this.sizes.center_radius_incomplete; - tile.circleText.fill = "red"; - tile.circleText.fontWeight = 'bold'; - } - }, - - setTileVisible: function (tile, visible) { - tile.visible = visible; - tile.circle.visible = tile.visible; - tile.circleCenter.visible = tile.visible; - tile.circleText.visible = tile.visible; - }, - - setTileColor: function(tile, color, stackPointer) { - this.setTileVisible(tile, true); - tile.colorIndex = parseInt(color); - tile.circleText.text = String(tile.colorIndex); - - if (color > 0) { - color = ((color - 1) % (this.colorPairs.length -1)) + 1; - } - var colorStops = this.colorPairs[color]; - - tile.circle.setGradient("fill", { - y2: 2 * this.sizes.tile_radius, - colorStops: colorStops - }); - }, - - _addLargeRectangleOverlay: function() { - - this.overLay = new fabric.Rect({ - width: 632, - height: 482, - left: 0, - top: 0, - opacity: 0.0, - originX: 'left', - originY: 'top', - lockMovementY: true, - lockMovementX: true, - selectable: false - }); - - this.mainFabricCanvas.add(this.overLay); - } - }; - } -})(jQuery, fabric); - -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.createField = function() { - // It create those fields in the tab , there is 4 types of them. - return { - - _createField: function(field) { - switch (field.data.type) { - case "text": - this._createTextField(field); - break; - - case "numeric": - this._createNumericField(field); - break; - - case "select": - this._createSelectField(field); - break; - - case "multiselect": - this._createMultiSelectField(field); - break; - - case "boolean": - this._createBooleanField(field); - break; - - case "multiplex": - this._createMultiplexField(field); - break; - } - }, - - _createTextField: function(field) { - var id = field.id; - var that = this; - var input = this._createElement("<input>").attr("id", id) - .addClass("plate-setup-tab-input"); - - field.root.find(".plate-setup-tab-field-container").append(input); - that.defaultWell[id] = null; - - field.parseValue = function(v) { - if (v) { - v = String(v); - } else { - v = null; - } - return v; - }; - - field.getValue = function() { - var v = input.val().trim(); - if (v == "") { - v = null; - } - return v; - }; - - field.setValue = function(v) { - input.val(v); - }; - - field.getText = function(v) { - if (v == null) { - return ""; - } - return v; - }; - - field.disabled = function(bool) { - field.input.prop("disabled", bool); - }; - - field.parseText = field.parseValue; - - input.on("input", function(e, generated) { - field.onChange(); - }); - - field.input = input; - }, - - _createOpts: function(config) { - var opts = { - allowClear: true, - placeholder: "select", - minimumResultsForSearch: 10 - }; - - if (config.options) { - opts.data = config.options; - } else if (config.query) { - var query = config.query; - if (config.delay) { - query = this._debounce(config.delay, query); - } - opts.query = query; - } else { - throw "Must specify data or query"; - } - return opts; - }, - - _createSelectField: function(field) { - var id = field.id; - var that = this; - var input = this._createElement("<input/>").attr("id", id) - .addClass("plate-setup-tab-select-field"); - - field.root.find(".plate-setup-tab-field-container").append(input); - that.defaultWell[id] = null; - - var opts = that._createOpts(field.data); - var optMap = {}; - opts.data.forEach(function(opt) { - optMap[opt.id] = opt; - }); - - input.select2(opts); - - field.parseValue = function(value) { - var v = value; - - if (v == "") { - v = null; - } - if (v == null) { - return null; - } - if (v in optMap) { - return optMap[v].id; - } else { - throw "Invalid value " + value + " for select field " + id; - } - }; - - field.disabled = function(bool) { - field.input.prop("disabled", bool); - }; - - field.getValue = function() { - var v = input.select2('data'); - return v ? v.id : null; - }; - - field.setValue = function(v) { - if (v) { - v = optMap[v]; - } - input.select2('data', v); - }; - - field.setOpts = function(v) { - input.select2('data', {}); - opts.data = v || []; - input.select2(opts); - }; - - field.getText = function(v) { - if (v == null) { - return ""; - } - return optMap[v].text; - }; - - field.parseText = function(value) { - var v = value; - - if (v == "") { - v = null; - } - if (v == null) { - return null; - } - if (v in optMap) { - return optMap[v].text; - } else { - throw "Invalid text value " + value + " for select field " + id; - } - }; - - input.on("change", function(e, generated) { - field.onChange(); - }); - - field.input = input; - }, - - _createMultiSelectField: function(field) { - var id = field.id; - var that = this; - var input = this._createElement("<input/>").attr("id", id) - .addClass("plate-setup-tab-multiselect-field"); - input.attr("multiple", "multiple"); - - field.root.find(".plate-setup-tab-field-container").append(input); - that.defaultWell[id] = null; - - var separator = ","; - var opts = that._createOpts(field.data); - opts.multiple = true; - var optMap = {}; - opts.data.forEach(function(opt) { - optMap[opt.id] = opt; - }); - input.select2(opts); - - field.disabled = function(bool) { - field.input.prop("disabled", bool); - }; - - field.parseValue = function(value) { - var v = value; - if (v && v.length) { - v = v.map(function(opt) { - if (opt in optMap) { - return optMap[opt].id; - } else { - throw "Invalid value " + opt + " for multiselect field " + id; - } - }); - } else { - v = null; - } - return v; - }; - - field.setOpts = function(v) { - var allOpts = field.data.options; - var selectedVal = []; - for (var id in allOpts) { - var curOpts = allOpts[id]; - if (v.indexOf(curOpts["id"]) >= 0) { - selectedVal.push(curOpts); - } - } - - opts.data = selectedVal; - input.select2(opts); - }; - - field.getValue = function() { - var v = input.select2('data'); - if (v.length) { - return v.map(function(i) { - return i.id; - }); - } - return null; - }; - - field.setValue = function(v) { - v = v || []; - v = v.map(function(i) { - return optMap[i]; - }); - input.select2('data', v); - }; - - field.getText = function(v) { - if (v == null) { - return ""; - } - if (v.length > 0) { - return v.map(function(v) { - return optMap[v].text - }).join("; "); - } - return ""; - }; - - field.multiOnChange = function (added, removed) { - if (added) { - added = added.id.toString(); - } - if (removed) { - removed = removed.id.toString(); - } - var data = { - }; - data[field.id] = { - multi: true, - added: added, - removed: removed - }; - - that._addAllData(data); - }; - - field.parseText = function(value){ - var v = value; - if (v && v.length) { - v = v.map(function(opt) { - if (opt in optMap) { - return optMap[opt].text; - } else { - throw "Invalid text value " + opt + " for multiselect field " + id; - } - }); - } else { - v = null; - } - return v; - }; - - input.on("change", function(e, generated) { - var added = e.added; - var removed = e.removed; - //field.onChange(); - field.multiOnChange(added, removed); - }); - - field.input = input; - - that._createDeleteButton(field); - }, - - _createNumericField: function(field) { - var id = field.id; - var data = field.data; - var that = this; - var input = this._createElement("<input>").addClass("plate-setup-tab-input") - .attr("placeholder", data.placeholder || "").attr("id", id); - - field.root.find(".plate-setup-tab-field-container").append(input); - that.defaultWell[id] = null; - - // Adding unit - var units = data.units || []; - var defaultUnit = data.defaultUnit || null; - var unitInput = null; - if (defaultUnit) { - if (units.length) { - if (units.indexOf(defaultUnit) < 0) { - defaultUnit = units[0]; - } - } else { - units = [defaultUnit]; - } - } else { - if (units.length) { - defaultUnit = units[0]; - } - } - - if (units.length) { - field.units = units; - field.hasUnits = true; - field.defaultUnit = defaultUnit; - if (units.length == 1) { - var unitText = $("<div></div>").addClass("plate-setup-tab-unit"); - unitText.text(defaultUnit); - field.root.find(".plate-setup-tab-field-container").append(unitText); - } else { - unitInput = this._createElement("<input/>").attr("id", id) - .addClass("plate-setup-tab-label-select-field"); - - field.root.find(".plate-setup-tab-field-container").append(unitInput); - - var selected = null; - var unitData = units.map(function(unit) { - var o = { - id: unit, - text: unit - }; - if (unit == defaultUnit) { - selected = o; - } - return o; - }); - - var opts = { - data: unitData, - allowClear: false, - minimumResultsForSearch: 10 - }; - - unitInput.select2(opts); - unitInput.select2("data", selected); - } - } - - field.disabled = function(bool) { - field.input.prop("disabled", bool); - if (unitInput) { - unitInput.prop("disabled", bool); - } - }; - - field.setUnitOpts = function(opts) { - field.units = opts || null; - field.defaultUnit = null; - - var newUnits = []; - var selected = null; - if (field.units && field.units.length) { - field.defaultUnit = field.units[0]; - newUnits = field.units.map(function(curUnit) { - var cleanUnit = { - id: curUnit, - text: curUnit - }; - if (curUnit == field.defaultUnit) { - selected = cleanUnit; - } - return cleanUnit; - }); - } - - var newOpts = { - data: newUnits, - allowClear: false, - minimumResultsForSearch: 10 - }; - unitInput.select2(newOpts); - unitInput.select2("data", selected); - }; - - field.parseValue = function(value) { - var v; - if ($.isPlainObject(value)) { - if (field.hasUnits) { - v = field.parseRegularValue(value.value); - if (v === null) { - return null; - } - return { - value: v, - unit: field.parseUnit(value.unit) - }; - } else { - throw "Value must be plain numeric for numeric field " + id; - } - } else { - if (field.hasUnits) { - v = field.parseRegularValue(value); - if (v === null) { - return null; - } - return { - value: v, - unit: field.defaultUnit - }; - } else { - return field.parseRegularValue(value); - } - } - }; - - field.getValue = function() { - var v = field.getRegularValue(); - - if ((v === null) || isNaN(v)) { - return null; - } else if (field.hasUnits) { - var returnVal = { - value: v, - unit: field.getUnit() - }; - - if (field.data.hasMultiplexUnit) { - // include unitTypeId and UnitId to returnVal - for (var unitTypeKey in field.data.unitMap) { - var unitTypeUnits = field.data.unitMap[unitTypeKey]; - unitTypeUnits.forEach(function(unit) { - if (unit.text === returnVal.unit) { - returnVal['unitTypeId'] = unitTypeKey; - returnVal['unitId'] = unit.id; - } - }) - } - } - return returnVal; - } else { - return v; - } - }; - - field.setValue = function(value) { - if (field.hasUnits) { - if ($.isPlainObject(value)) { - field.setUnit(value.unit || field.defaultUnit); - field.setRegularValue(value.value); - - } else { - field.setRegularValue(value); - field.setUnit(field.defaultUnit) - } - } else { - field.setRegularValue(value); - } - }; - - field.parseRegularValue = function(value) { - if (value == null) { - return null; - } - var v = String(value).trim(); - if (v === "") { - return null; - } - v = Number(value); - if (isNaN(v)) { - throw "Invalid value " + value + " for numeric field " + id; - } - return v; - }; - - field.getRegularValue = function() { - var v = input.val().trim(); - if (v == "") { - v = null; - } else { - v = Number(v); - } - return v; - }; - - field.setRegularValue = function(value) { - input.val(value); - }; - - field.parseUnit = function(unit) { - if (unit == null || unit === "") { - return field.defaultUnit; - } - for (var i = 0; i < units.length; i++) { - if (unit.toLowerCase() == units[i].toLowerCase()) { - return units[i]; - } - } - throw "Invalid unit " + unit + " for field " + id; - }; - - field.getUnit = function() { - if (unitInput) { - return unitInput.val(); - } else { - return field.defaultUnit; - } - }; - - field.setUnit = function(unit) { - if (unitInput) { - unit = unit || field.defaultUnit; - if (unit != null) { - unit = { - id: unit, - text: unit - }; - } - unitInput.select2("data", unit); - } - }; - - // val now contains unit - field.getText = function(val) { - if (typeof(val) === 'object' && val) { - var v = val.value; - var u = val.unit; - if (v == null) { - return ""; - } - v = v.toString(); - if (!u) { - u = defaultUnit; - } - if (u) { - v = v + " " + u; - } - return v; - } else { - return field.getRegularText(val); - } - }; - - field.getRegularText = function(v) { - if (v == null) { - return ""; - } - v = v.toString(); - return v; - }; - - field.parseText = function(v){ - var textVal = field.parseValue(v); - if (textVal && typeof(textVal) === "object"){ - return textVal.value + textVal.unit; - } else if (textVal) { - return textVal - } else { - return null; - } - }; - - input.on("input", function() { - var v = field.getRegularValue(); - if (isNaN(v)) { - //flag field as invalid - input.addClass("invalid"); - } else { - input.removeClass("invalid"); - } - field.onChange(); - }); - if (unitInput) { - unitInput.on("change", function() { - field.onChange(); - }); - } - - field.input = input; - field.unitInput = unitInput; - }, - - _createBooleanField: function(field) { - var id = field.id; - var that = this; - var input = this._createElement("<input/>").attr("id", id) - .addClass("plate-setup-tab-select-field"); - that.defaultWell[id] = null; - - field.root.find(".plate-setup-tab-field-container").append(input); - var tval = { - id: "true", - text: "true" - }; - var fval = { - id: "false", - text: "false" - }; - var opts = { - data: [tval, fval], - placeholder: "select", - allowClear: true, - minimumResultsForSearch: -1, - initSelection: function(element, callback) { - var v = element.val(); - callback({ - id: v, - text: v - }); - } - }; - - input.select2(opts); - - field.disabled = function(bool) { - field.input.prop("disabled", bool); - }; - - field.parseValue = function(value) { - if (value == null) { - return null; - } - var v = String(value).trim().toLowerCase(); - if (v == "true") { - v = true; - } else if (v == "false") { - v = false; - } else if (v == "") { - v = null; - } else { - throw "Invalid value " + value + " for boolean field " + id; - } - return v; - }; - - field.getValue = function() { - var v = input.val(); - switch (v) { - case "true": - return true; - case "false": - return false; - default: - return null; - } - }; - - field.setValue = function(v) { - if (v == true || v == "true") { - v = tval; - } else if (v == false || v == "false") { - v = fval; - } else { - v = null; - } - input.select2('data', v); - }; - - field.getText = function(v) { - if (v == null) { - return ""; - } - return v.toString(); - }; - - field.parseText = field.parseValue; - - input.on("change", function(e) { - field.onChange(); - }); - - field.input = input; - }, - - _createMultiplexField: function(field) { - var that = this; - // make correct multiplex data - this._createMultiSelectField(field); - // overwrite default well for multiplex field - that.defaultWell[field.id] = []; - - // single select - var nameContainer1 = that._createElement("<div></div>").addClass("plate-setup-tab-name-singleSelect").text("Select to edit"); - var fieldContainer1 = that._createElement("<div></div>").addClass("plate-setup-tab-field-container-singleSelect"); - field.root.find(".plate-setup-tab-field-right-side").append(nameContainer1, fieldContainer1); - - field.singleSelect = this._createElement("<input/>").attr("id", field.id + "SingleSelect") - .addClass("plate-setup-tab-multiplex-single-select-field"); - - field.singleSelect.appendTo(fieldContainer1); - - field.singleSelectValue = function () { - var v = field.singleSelect.select2("data"); - if (v != null) { - v = v.id; - } - return v; - }; - - var setSingleSelectOptions = function (v, selected_v) { - var opts = { - allowClear: false, - placeholder: "select", - minimumResultsForSearch: 10, - data: v || [] - } - if (!selected_v) { - if (opts.data.length) { - selected_v = opts.data[0]; - } else { - selected_v = null; - } - } - field.singleSelect.select2('data', []); - field.singleSelect.select2(opts); - field.singleSelect.select2('data', selected_v); - field.singleSelect.prop("disabled", opts.data.length == 0); - }; - - var singleSelectChange = function () { - var v = field.singleSelectValue(); - - field.updateSubFieldUnitOpts(v); - - var curData = field.detailData || []; - var curSubField = null; - curData.forEach(function(val) { - if (val[field.id] === v) { - curSubField = val; - } - }); - - if (curSubField) { - // setvalue for subfield - field.subFieldList.forEach(function(subField) { - subField.disabled(false); - subField.setValue(curSubField[subField.id]); - }); - } else { - field.subFieldList.forEach(function(subField) { - subField.disabled(true); - subField.setValue(null); - }); - } - that.readOnlyHandler(); - }; - - setSingleSelectOptions([]); - - field.singleSelect.on("change", singleSelectChange); - - field._changeMultiFieldValue = function(added, removed) { - var newSubFieldValue = {}; - for (var subFieldName in field.data.multiplexFields) { - var subFieldId = field.data.multiplexFields[subFieldName].id; - newSubFieldValue[subFieldId] = null; - } - - var val; - if (added) { - if (added.value) { - val = added.value; - } else { - newSubFieldValue[field.id] = added.id; - val = newSubFieldValue; - } - added = { - id: added.id, - value: val - }; - } - - if (removed) { - if (removed.value){ - val = removed.value; - } else { - newSubFieldValue[field.id] = removed.id; - val = newSubFieldValue; - } - removed = { - id: removed.id, - value: val - }; - } - - var data = {}; - data[field.id] = { - multi: true, - added: added, - removed: removed - }; - that._addAllData(data); - }; - - var multiselectSetValue = field.setValue; - - // overwrite multiplex set value - field.setValue = function(v) { - // used to keep track of initially loaded multiplex data - field.detailData = v; - var multiselectValues = null; - if (v && v.length) { - multiselectValues = v.map(function(val) { - return val[field.id] - }); - } - - multiselectSetValue(multiselectValues); - var newOptions = field.input.select2('data') || []; - setSingleSelectOptions(newOptions); - singleSelectChange(); - }; - - field.disabled = function(bool) { - field.input.prop("disabled", bool); - field.subFieldList.forEach(function(subField) { - subField.disabled(bool); - }); - if (bool) { - nameContainer1.text("Select to inspect"); - } else { - nameContainer1.text("Select to edit"); - } - }; - - field.parseValue = function(value) { - var v = value; - if (v && v.length) { - v = v.map(function(opt) { - var valMap = {}; - valMap[field.id] = opt[field.id]; - for (var subFieldId in opt) { - field.subFieldList.forEach(function(subField) { - if (subField.id === subFieldId) { - valMap[subField.id] = subField.parseValue(opt[subFieldId]); - } - }); - } - return valMap; - }); - } else { - v = null; - } - return v; - }; - - field.updateSubFieldUnitOpts = function(val) { - var curOpts; - field.data.options.forEach(function(opt) { - if (opt.id === val) { - curOpts = opt; - } - }); - field.subFieldList.forEach(function(subField) { - if (subField.data.hasMultiplexUnit) { - if (curOpts && curOpts.hasOwnProperty("unitOptions")) { - subField.setUnitOpts(curOpts.unitOptions[subField.id]); - } else { - subField.setUnitOpts(null); - } - } - }) - }; - - field.multiOnChange = function(added, removed) { - field._changeMultiFieldValue(added, removed); - var v = field.getValue(); - var curData = field.detailData; - var curIds = []; - var curOpt = null; - //reshape data for saveback - if (curData) { - curIds = curData.map(function(val) { - return val[field.id] - }); - } - - var newMultiplexVal = []; - var selectList = []; - if (v) { - v.forEach(function(selectedVal) { - if (curData) { - curData.forEach(function(val) { - if (val[field.id] === selectedVal) { - newMultiplexVal.push(val) - } - }); - } - // cases when adding new data - if (curIds.indexOf(selectedVal) < 0) { - var newVal = {}; - newVal[field.id] = selectedVal; - - field.updateSubFieldUnitOpts(selectedVal); - field.subFieldList.forEach(function(subfield) { - // special handling for subfield which has multiplexUnit - if (subfield.hasUnits) { - if (subfield.data.hasMultiplexUnit) { - subfield.disabled(false); - field.data.options.forEach(function(opt) { - if (opt.id === selectedVal) { - var val = { - value: null, - unit: subfield.units[0] - }; - newVal[subfield.id] = subfield.parseValue(val); - } - }); - } else { - if (subfield.data.units) { - if (subfield.data.units.length > 1){ - subfield.disabled(false); - } - } - var val = { - value: null, - unit: subfield.defaultUnit - }; - newVal[subfield.id] = subfield.parseValue(val); - } - } - else { - newVal[subfield.id] = subfield.parseValue(null); - } - }); - newMultiplexVal.push(newVal); - } - }); - - // make data for single select options - v.forEach(function(selectId) { - field.data.options.forEach(function(opt) { - if (opt.id === selectId) { - selectList.push(opt); - } - }); - }); - // set the newest selected to be the current obj - curOpt = selectList[v.length - 1]; - } - - field.detailData = newMultiplexVal; - setSingleSelectOptions(selectList, curOpt); - singleSelectChange(); - }; - - field.getText = function(v) { - if (v === null) { - return ""; - } - // get subfields that is selected from the checkbox - if (field.id in that.globalSelectedMultiplexSubfield) { - var checkedSubfields = that.globalSelectedMultiplexSubfield[field.id]; - var returnVal = []; - for (var valIdx in v) { - var subV = v[valIdx]; - var subText = []; - for (var optId in field.data.options) { - var opt = field.data.options[optId]; - if (opt.id === subV[field.id]) { - subText.push(opt.text); - } - } - field.subFieldList.forEach(function(subField) { - if (checkedSubfields.indexOf(subField.id) >= 0) { - var x = subField.getText(subV[subField.id]); - subText.push(subField.name + ": " + x); - } - }); - returnVal.push("{" + subText.join(", ") + "}"); - } - return returnVal.join(";"); - } - }; - - field.parseText = function(v) { - if (v === null) { - return ""; - } else { - var returnVal = []; - for (var valIdx in v) { - var subV = v[valIdx]; - var subText = []; - for (var optId in field.data.options) { - var opt = field.data.options[optId]; - if (opt.id === subV[field.id]) { - subText.push(opt.text); - } - } - field.subFieldList.forEach(function(subField) { - var x = subField.getText(subV[subField.id]); - if (x) { - subText.push(x); - } - }); - returnVal.push(subText); - } - return returnVal; - } - }; - - field.checkMultiplexCompletion = function(valList) { - var valCount = 0; - var completionPct = 0; - var include = false; - function getSubfieldStatus (vals) { - var req = 0; - var fill = 0; - for (var subFieldId in field.subFieldList) { - var subField = field.subFieldList[subFieldId]; - var curVal = vals[subField.id]; - if (subField.required) { - include = true; - req++; - if (typeof(curVal) === 'object' && curVal) { - if (curVal.value) { - fill++; - } - } else if (curVal) { - fill++; - } - } - } - return fill/req; - } - - // for cases has value in multiplex field - if (valList) { - if (valList.length > 0){ - for (var idx in valList) { - valCount++; - var vals = valList[idx]; - completionPct += getSubfieldStatus(vals); - } - } else if (field.required) { - include = true; - valCount = 1; - } - } else if (field.required) { - include = true; - valCount = 1; - } - - return { - include: include, - completionPct: completionPct/valCount - }; - }; - - // valList contains all of the vals for selected val - field.applyMultiplexSubFieldColor = function(valList){ - function updateSubFieldWarningMap (vals) { - for (var subFieldId in field.subFieldList) { - var subField = field.subFieldList[subFieldId]; - // loop through each well's multiplexval list - if (vals === null){ - if (field.required && subField.required){ - subFieldWarningMap[subField.id].warningStatus.push(true); - } - } else if (typeof(vals) === "object") { - if (vals.length === 0) { - if (field.required && subField.required){ - subFieldWarningMap[subField.id].warningStatus.push(true); - } - } else { - for (var multiplexIdx in vals) { - var curVal = vals[multiplexIdx][subField.id]; - if (subField.required) { - if (typeof(curVal) === 'object' && curVal) { - if (!curVal.value) { - subFieldWarningMap[subField.id].warningStatus.push(true); - } else { - subFieldWarningMap[subField.id].warningStatus.push(false); - } - } else if (!curVal) { - subFieldWarningMap[subField.id].warningStatus.push(true); - } else { - subFieldWarningMap[subField.id].warningStatus.push(false); - } - } - } - } - } - } - } - - var subFieldWarningMap = {}; - field.subFieldList.forEach(function(subField){ - if (subField.required) { - subFieldWarningMap[subField.id] = { - field: subField, - warningStatus: [] - }; - } - }); - - valList.forEach(function(multiplexVals) { - updateSubFieldWarningMap(multiplexVals); - }); - // turn off main field when all subfield are filled - - var requiredSubField = []; - var mainFieldStatus = []; - for (var subFieldId in subFieldWarningMap){ - var subField = subFieldWarningMap[subFieldId].field; - if (subFieldWarningMap[subFieldId].warningStatus.indexOf(true) >= 0) { - var text = subField.name + " is a required subfield for " + field.name + ", please make sure all " + field.name + " have " + subField.name; - if (field.required){ - that.fieldWarningMsg(subField, text, true); - mainFieldStatus.push(true); - } else { - that.fieldWarningMsg(subField, text, true); - mainFieldStatus.push(true); - } - } else { - that.fieldWarningMsg(subField, "none", false); - mainFieldStatus.push(false); - } - } - var mainFieldWarning = false; - if (mainFieldStatus.indexOf(true) < 0) { - mainFieldWarning = false; - } else { - mainFieldWarning = true; - } - var warningText; - if (field.required) { - warningText = field.name + " is a required field, please also fix missing required subfield(s) below"; - } else { - warningText = field.name + " is not a required field, please fix missing required subfield(s) below or remove selected " + field.name; - } - that.fieldWarningMsg(field, warningText, mainFieldWarning); - }; - - field.parseMainFieldVal = function(val) { - var optMap = field.data.options; - for (var idx = 0; idx < optMap.length; idx++){ - var curOpt = optMap[idx]; - if (curOpt.id === val){ - return curOpt.text - } - } - }; - }, - - _deleteDialog: function (field) { - var that = this; - - var valMap = field.allSelectedMultipleVal; - var valToRemove; - if (valMap) { - valToRemove = Object.keys(valMap); - } else { - valToRemove = []; - } - - - var dialogDiv = $("<div/>").addClass("delete-dialog modal"); - $('body').append(dialogDiv); - - function killDialog() { - dialogDiv.hide(); - dialogDiv.remove(); - } - - var dialogContent = $("<div/>").addClass("modal-content").appendTo(dialogDiv); - var tableArea = $("<div/>").appendTo(dialogContent); - var buttonRow = $("<div/>").addClass("dialog-buttons").css("justify-content", "flex-end").appendTo(dialogContent); - - if (valToRemove.length > 0){ - // apply CSS property for table - $("<p/>").text(field.name + " in selected wells: choose items to delete and click the delete button below").appendTo(tableArea); - - var table = that._deleteDialogTable(field, valMap); - table.appendTo(tableArea); - table.addClass("plate-popout-table"); - table.find('td').addClass("plate-popout-td"); - table.find('th').addClass("plate-popout-th"); - table.find('tr').addClass("plate-popout-tr"); - if (!that.readOnly) { - var deleteCheckedButton = $("<button class='multiple-field-manage-delete-button'>Delete Checked Items</button>"); - buttonRow.append(deleteCheckedButton); - deleteCheckedButton.click(function() { - table.find("input:checked").each(function () { - var val = this.value; - field.multiOnChange(null, {id: val}); - }); - // refresh selected fields after updating the multiplex field value - that.decideSelectedFields(); - killDialog(); - }); - } - - } else { - $("<p/>").text("No " + field.name + " in the selected wells").appendTo(tableArea); - } - - var cancelButton = $("<button>Cancel</button>"); - buttonRow.append(cancelButton); - cancelButton.click(killDialog); - - dialogDiv.show(); - - window.onclick = function(event) { - if (event.target == dialogDiv[0]) { - killDialog(); - } - } - }, - - _deleteDialogTable: function (field, valMap) { - var that = this; - var colName = [field.name, "Counts"]; //Added because it was missing... no idea what the original should have been - if (!that.readOnly) { - colName.push("Delete"); - } - var table = $('<table/>'); - var thead = $('<thead/>').appendTo(table); - var tr = $('<tr/>').appendTo(thead); - - tr.append(colName.map(function (text) { - return $('<th/>').text(text); - })); - - var tbody = $("<tbody/>").appendTo(table); - - field.data.options.forEach(function (opt) { - if (opt.id in valMap) { - var tr = $('<tr/>').appendTo(tbody); - var checkbox = $("<input type='checkbox'>").prop("value", opt.id); - $("<td/>").text(opt.text).appendTo(tr); - $("<td/>").text(valMap[opt.id]).appendTo(tr); - if (!that.readOnly) { - $("<td/>").append(checkbox).appendTo(tr); - } - } - }); - - return table; - }, - - _createDeleteButton: function (field) { - var that = this; - var deleteButton = $("<button/>").addClass("plate-setup-remove-all-button"); - deleteButton.id = field.id + "Delete"; - deleteButton.text("Manage " + field.name + "..."); - var buttonContainer = that._createElement("<div></div>").addClass("plate-setup-remove-all-button-container"); - buttonContainer.append(deleteButton); - - field.deleteButton = deleteButton; - field.root.find(".plate-setup-tab-field-right-side").append(buttonContainer); - - deleteButton.click(function () { - that._deleteDialog(field); - }); - } - - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.engine = function(THIS) { - // Methods which look after data changes and stack up accordingly - // Remember THIS points to plateLayOutWidget and 'this' points to engine - // Use THIS to refer parent this. - return { - engine: { - - derivative: {}, - stackUpWithColor: {}, - stackPointer: 2, - - wellEmpty: function (well) { - for (var prop in well) { - var curVal = well[prop]; - if (curVal !== null && curVal !== undefined) { - if (Array.isArray(curVal)) { - if (curVal.length > 0) { - return false; - } - } else { - return false; - } - } - } - return true; - }, - - searchAndStack: function() { - // This method search and stack the change we made. - this.stackUpWithColor = {}; - this.stackPointer = 1; - var derivativeJson = {}; - for (var idx in this.derivative) { - var data = this.derivative[idx]; - var wellData = {}; - for (var i = 0; i < THIS.globalSelectedAttributes.length; i++) { - var attr = THIS.globalSelectedAttributes[i]; - - if (attr in THIS.globalSelectedMultiplexSubfield){ - var selectedSubFields = THIS.globalSelectedMultiplexSubfield[attr]; - var newMultiplexVal = []; - for (var multiplexIdx in data[attr]){ - var curMultiplexVals = data[attr][multiplexIdx]; - var newVal = {}; - newVal[attr] = curMultiplexVals[attr]; - selectedSubFields.forEach(function (subFieldId) { - newVal[subFieldId] = curMultiplexVals[subFieldId]; - }); - newMultiplexVal.push(newVal); - } - wellData[attr] = newMultiplexVal; - } else { - if (data[attr] != null) { - wellData[attr] = data[attr]; - } - } - } - if ($.isEmptyObject(wellData)) { - derivativeJson[idx] = null; - } else { - derivativeJson[idx] = JSON.stringify(wellData); - } - } - - while (!$.isEmptyObject(derivativeJson)) { - var keys = Object.keys(derivativeJson).map(function (k) {return parseFloat(k, 10);}); - keys.sort(function (a, b) {return a-b;}); - - var refDerivativeIndex = keys[0]; - var referenceDerivative = derivativeJson[refDerivativeIndex]; - var arr = []; - - if (!referenceDerivative) { - // if no checked box has value, push it to first spot - if (this.stackUpWithColor[0]) { - this.stackUpWithColor[0].push(refDerivativeIndex); - } else { - this.stackUpWithColor[0] = [refDerivativeIndex]; - } - - delete derivativeJson[refDerivativeIndex]; - } else { - // if checked boxes have values - for (var i = 0; i < keys.length; i++) { - var idx = keys[i]; - if (referenceDerivative == derivativeJson[idx]) { - arr.push(idx); - this.stackUpWithColor[this.stackPointer] = arr; - delete derivativeJson[idx]; - } - } - if (arr.length > 0) - this.stackPointer++; - } - } - }, - - applyColors: function() { - - var wholeNoTiles = 0; - var wholePercentage = 0; - - THIS.addBottomTableHeadings(); - - for (var i = 0; i < THIS.allTiles.length; i++) { - var tile = THIS.allTiles[i]; - THIS.setTileVisible(tile, false); - } - - for (var color = 0; color < this.stackPointer; color++) { - var arr = this.stackUpWithColor[color]; - if (arr) { - THIS.addBottomTableRow(color, arr); - - for (var tileIndex in arr) { - wholeNoTiles++; - var index = this.stackUpWithColor[color][tileIndex]; - var tile = THIS.allTiles[index]; - var well = this.derivative[index]; - THIS.setTileColor(tile, color, this.stackPointer); - // Checks if all the required fields are filled - var completion = this.checkCompletion(well, tile); - THIS.setTileComplete(tile, completion == 1); - wholePercentage = wholePercentage + completion; - } - } - } - - wholePercentage = Math.floor(100 * wholePercentage / wholeNoTiles); - - if (isNaN(wholePercentage)) { - THIS.overLayTextContainer.text("Completion Percentage: 0%"); - } else { - THIS.overLayTextContainer.text("Completion Percentage: " + wholePercentage + "%"); - } - }, - - checkCompletion: function(wellData, tile) { - var req = 0; - var fill = 0; - for (var i = 0; i < THIS.fieldList.length; i++) { - var field = THIS.fieldList[i]; - if (field.checkMultiplexCompletion){ - // also apply color - var multiplexStatus = field.checkMultiplexCompletion(wellData[field.id]); - if (multiplexStatus.include) { - fill += multiplexStatus.completionPct; - req++; - } - } else { - if (field.required) { - req++; - if (wellData[field.id] !== null) { - fill++; - } - } - } - } - if (req === fill) { - return 1; - } - return fill / req; - }, - } - } - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.fabricEvents = function() { - // This object contains Menu items and how it works; - return { - colorToIndex: {}, - startCoords: { - x: 0, - y: 0 - }, - focalWell: { - row: 0, - col: 0 - }, - selectedAreas: [], - - _clickCoords: function(evt) { - //Get XY Coords for a given event. - var rect = evt.e.target.getBoundingClientRect(); - return { - x: evt.e.clientX - rect.left, - y: evt.e.clientY - rect.top - }; - }, - - _fabricEvents: function() { - // Set up event handling. - var that = this; - - $(that.target).on("getPlates", function(evt, data) { - // This method should be compatable to redo/undo. - that.getPlates(JSON.parse(data)); - }); - - that.mainFabricCanvas.on("mouse:down", function(evt) { - // Start selecting new area - that.selecting = true; - var coords = that._clickCoords(evt); - - var areas = that.selectedAreas.slice(); - var focalWell = that.focalWell; - var startCoords = that._wellToCoords(focalWell, true); - var rect = that._coordsToRect(startCoords, coords); - - if (evt.e.ctrlKey) { - //adding new area - startCoords = coords; - rect = that._coordsToRect(startCoords, coords); - focalWell = that._coordsToWell(startCoords); - if (evt.e.shiftKey) { - //replacing existing areas - areas = [that._rectToArea(rect)]; - } else { - areas.push(that._rectToArea(rect)); - } - } else { - if (evt.e.shiftKey) { - //Altering last area - areas[areas.length - 1] = that._rectToArea(rect); - } else { - //Creating new area - startCoords = coords; - rect = that._coordsToRect(startCoords, coords); - focalWell = that._coordsToWell(startCoords); - areas = [that._rectToArea(rect)]; - } - } - - that.startCoords = startCoords; - that.setSelection(areas, focalWell); - that.mainFabricCanvas.renderAll(); - }); - - that.mainFabricCanvas.on("mouse:move", function(evt) { - if (that.selecting) { - // continue selecting new area - var areas = that.selectedAreas.slice(); - var endCoords = that._clickCoords(evt); - var rect = that._coordsToRect(that.startCoords, endCoords); - var area = that._rectToArea(rect); - if (area) { - areas[areas.length - 1] = area; - } - - that.setSelection(areas, that.focalWell); - that.mainFabricCanvas.renderAll(); - } - - }); - - that.mainFabricCanvas.on("mouse:up", function(evt) { - // finish selecting new area - that.selecting = false; - var areas = that.selectedAreas.slice(); - var endCoords = that._clickCoords(evt); - var rect = that._coordsToRect(that.startCoords, endCoords); - var area = that._rectToArea(rect); - if (area) { - areas[areas.length - 1] = area; - } - - that.setSelection(areas, that.focalWell); - that.decideSelectedFields(); - that.mainFabricCanvas.renderAll(); - that._trigger("selectedWells", null, {selectedAddress: that.getSelectedAddress()}); - }); - }, - - setSelection: function(areas, focalWell) { - this.selectedAreas = areas; - this.focalWell = focalWell; - this.allSelectedObjects = this._areasToTiles(areas); - this._setSelectedTiles(); - this._setFocalWellRect(this.focalWell); - document.activeElement.blur(); - }, - - _setFocalWellRect: function(well) { - var flag; - // check if not allow to add or delete existing wells - if (this.disableAddDeleteWell) { - var address = this.locToAddress({ - r: well.row, - c: well.col - }); - if (this.addressAllowToEdit.indexOf(address) < 0) { - flag = false; - this.setFieldsDisabled(true); - } else { - flag = true; - this.setFieldsDisabled(false); - } - } else if (well) { - flag = true; - } - - if (flag) { - var rect = this._areaToRect(this._wellToArea(well)); - var strokeWidth = 2; - if (this.focalWellRect) { - //update focalWellRect - this.focalWellRect.top = rect.top; - this.focalWellRect.left = rect.left; - this.focalWellRect.width = rect.width - strokeWidth; - this.focalWellRect.height = rect.height - strokeWidth; - } else { - //create focalWellRect - this.focalWellRect = new fabric.Rect({ - width: rect.width - strokeWidth, - height: rect.height - strokeWidth, - left: rect.left, - top: rect.top, - fill: null, - strokeWidth: strokeWidth, - stroke: "black", - selectable: false - }); - this.mainFabricCanvas.add(this.focalWellRect); - } - } else { - //clear focalWellRect - this.mainFabricCanvas.remove(this.focalWellRect); - this.focalWellRect = null; - } - }, - - _setSelectedTiles: function() { - // Update selected tile display only - var selectedTiles = this.allSelectedObjects; - this.allTiles.forEach(function(tile) { - var selected = selectedTiles.indexOf(tile) >= 0; - tile.highlight.visible = selected; - }) - }, - - _getSelectedWells: function () { - var that = this; - return this.allSelectedObjects.map(function (tile) { - var well = that.engine.derivative[tile.index]; - if (!well) { - well = that.defaultWell; - } - return well; - }); - }, - - _getCommonFields: function (wells) { - if (wells.length) { - var referenceWell = wells[0]; - var referenceFields = $.extend(true, {}, referenceWell); - for (var i = 1; i < wells.length; i++) { - var fields = wells[i]; - for (var field in referenceFields) { - if (Array.isArray(referenceFields[field])) { - var refArr = referenceFields[field]; - var agrArr = []; - for (var j = 0; j < refArr.length; j++) { - var v = refArr[j]; - if (v && typeof(v) === "object") { - if (this.containsObject(v, fields[field])) { - agrArr.push(v); - } - } else { - if ($.inArray(v, fields[field]) >= 0) { - agrArr.push(v); - } - } - } - referenceFields[field] = agrArr; - } else { - if (fields[field] && typeof(fields[field]) ==="object" && referenceFields[field] && typeof(referenceFields[field]) ==="object"){ - if ((fields[field].value !== referenceFields[field].value) || (fields[field].unit !== referenceFields[field].unit)){ - delete referenceFields[field]; - } - } else if (referenceFields[field] != fields[field]) { - delete referenceFields[field]; - } - } - } - } - return referenceFields - } else { - return {}; - } - }, - - containsObject: function(obj, list) { - var equality = []; - if (list) { - list.forEach(function(val) { - //evaluate val and obj - var evaluate = []; - Object.keys(val).forEach(function(listKey){ - if (Object.keys(obj).indexOf(listKey) >= 0){ - var curVal = val[listKey]; - if (typeof(curVal) === 'object' && curVal) { - if (obj[listKey]){ - evaluate.push((curVal.unit === obj[listKey].unit) && (curVal.value === obj[listKey].value)); - } else { - // when obj[listKey] is null but curVal is not - evaluate.push(false); - } - } else { - evaluate.push(curVal === obj[listKey]); - } - } - }); - equality.push(evaluate.indexOf(false) < 0); - }); - return equality.indexOf(true) >= 0; - } else { - return false; - } - }, - - _getCommonWell: function (wells) { - if (wells.length) { - var referenceWell = wells[0]; - var referenceFields = $.extend(true, {}, referenceWell); - for (var i = 1; i < wells.length; i++) { - var well = wells[i]; - var fields = well; - for (var field in referenceFields) { - if (Array.isArray(referenceFields[field])) { - var refArr = referenceFields[field]; - var agrArr = []; - for (var j = 0; j < refArr.length; j++) { - var v = refArr[j]; - // for multiplex field - if (typeof(refArr[j]) ==="object"){ - if (this.containsObject(v, fields[field])) { - agrArr.push(v); - } - } else { - if ($.inArray(v, fields[field]) >= 0) { - agrArr.push(v); - } - } - } - referenceFields[field] = agrArr; - } else { - if (fields[field] && typeof(fields[field]) ==="object" && referenceFields[field] && typeof(referenceFields[field]) ==="object"){ - if ((fields[field].value !== referenceFields[field].value) || (fields[field].unit !== referenceFields[field].unit)){ - referenceFields[field] = null; - } - } else if (referenceFields[field] != fields[field]) { - referenceFields[field] = null; - } - - } - } - } - return referenceFields; - } else { - return this.defaultWell; - } - }, - - _getAllMultipleVal: function (wells) { - var multipleFieldList = this.multipleFieldList; - - multipleFieldList.forEach(function(multiplexField) { - if(wells.length) { - var curMultipleVal = {}; - wells.forEach(function (wellData) { - var id = multiplexField.id; - if (wellData[id]){ - if (wellData[id].length > 0) { - wellData[id].forEach(function (multipleVal) { - if (typeof(multipleVal) === 'object') { - if (multipleVal[id] in curMultipleVal) { - curMultipleVal[multipleVal[id]] ++; - } else { - curMultipleVal[multipleVal[id]] = 1; - } - } else { - if (multipleVal in curMultipleVal) { - curMultipleVal[multipleVal] ++; - - } else { - curMultipleVal[multipleVal] = 1; - } - } - }) - } - } - }); - multiplexField.allSelectedMultipleVal = curMultipleVal; - } else { - multiplexField.allSelectedMultipleVal = null - } - }); - }, - - decideSelectedFields: function() { - var wells = this._getSelectedWells(); - this._getAllMultipleVal(wells); - this.applyFieldWarning(wells); - var well = this._getCommonWell(wells); - this._addDataToTabFields(well); - }, - - // get well value differences for each well in wellsHash - getDifferentWellsVals: function(wellsHash) { - var wells = []; - for (var wellId in wellsHash){ - wells.push(wellsHash[wellId]); - } - var differentWellsVals = {}; - if (wells.length > 1){ - var commonWell = this._getCommonWell(wells); - var allFieldVal = {}; - for (var fieldIdx in wellsHash[0]) { - allFieldVal[fieldIdx] = []; - } - for (var wellIdx in wells){ - var diffWellVal = {}; - var curWellData = wells[wellIdx]; - for (var fieldId in curWellData) { - var commonVal = commonWell[fieldId]; - var curVal = curWellData[fieldId]; - var newVal = null; - if (Array.isArray(curVal)) { - // get uncommonVal - newVal = []; - for (var idx = 0; idx < curVal.length; idx ++){ - var curMultiVal = curVal[idx]; - // multiplex field - if (curMultiVal && typeof(curMultiVal === "object")){ - if (!this.containsObject(curMultiVal, commonVal)) { - newVal.push(curMultiVal); - if (!this.containsObject(curMultiVal, allFieldVal[fieldId])) { - allFieldVal[fieldId].push(curMultiVal); - } - } - } else { - if (commonVal.indexOf(curMultiVal) >= 0) { - newVal.push(curMultiVal); - if (!allFieldVal[fieldId].indexOf(curMultiVal) >= 0) { - allFieldVal[fieldId].push(curMultiVal); - } - } - } - } - } else if (curVal && typeof(curVal) === "object"){ - if (commonVal && typeof(commonVal) ==="object"){ - if (!((curVal.value === commonVal.value) || (curVal.unit === commonVal.unit))){ - newVal = curVal; - if (!this.containsObject(curVal, allFieldVal[fieldId])) { - allFieldVal[fieldId].push(curVal); - } - } - } else { - newVal = curVal; - if (!this.containsObject(curVal, allFieldVal[fieldId])) { - allFieldVal[fieldId].push(curVal); - } - } - } else if (curVal !== commonVal) { - newVal = curVal; - if (!allFieldVal[fieldId].indexOf(curVal) >= 0) { - allFieldVal[fieldId].push(curVal); - } - } - diffWellVal[fieldId] = newVal; - } - - - differentWellsVals[wellIdx] = diffWellVal; - } - - // clean up step for fields that are empty - for (var fieldId in allFieldVal) { - if (allFieldVal[fieldId].length === 0) { - for (var wellIdx in differentWellsVals){ - delete differentWellsVals[wellIdx][fieldId]; - } - } - } - - return differentWellsVals; - } else if (wellsHash[0]) { - var well = {}; - for (var fieldId in wellsHash[0]) { - var curVal = wellsHash[0][fieldId]; - if (Array.isArray(curVal)){ - if (curVal.length > 0) { - well[fieldId] = curVal - } - } else if (curVal){ - well[fieldId] = curVal; - } - } - return { - 0: well - }; - } - }, - - // get all wells that has data - getWellSetAddressWithData: function(){ - var address = []; - var derivative = this.engine.derivative; - for (var id in derivative){ - address.push(this.indexToAddress(id)); - } - return address; - } - - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -plateLayOutWidget.assets = function () { - return { - _assets: { - doImg: '✓', - dontImg: '', - warningImg: '⚠' - } - }; -}; - -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.interface = function() { - // interface holds all the methods to put the interface in place - return { - - _createInterface: function() { - - var divIdentifier = '<div></div>'; - this.container = this._createElement(divIdentifier).addClass("plate-setup-wrapper"); - this.topSection = this._createElement(divIdentifier).addClass("plate-setup-top-section"); - - this.topLeft = this._createElement(divIdentifier).addClass("plate-setup-top-left"); - this.topRight = this._createElement(divIdentifier).addClass("plate-setup-top-right"); - - this.overLayContainer = this._createElement(divIdentifier).addClass("plate-setup-overlay-container"); - this.canvasContainer = this._createElement(divIdentifier).addClass("plate-setup-canvas-container"); - - this._createOverLay(); - $(this.topLeft).append(this.overLayContainer); - - this._createCanvas(); - $(this.topLeft).append(this.canvasContainer); - - - $(this.topSection).append(this.topLeft); - $(this.topSection).append(this.topRight); - - $(this.container).append(this.topSection); - $(this.element).append(this.container); - - this._initiateFabricCanvas(); - - this._createTabAtRight(); - this._createTabs(); - - this._placePresetTabs(); - // Bottom of the screen - this._bottomScreen(); - // Canvas - this._canvas(); - - this.bottomForFirstTime(); - - var that = this; - this._setShortcuts(); - $(document.body).keyup(function(e) { - that._handleShortcuts(e); - }); - - this._configureUndoRedoArray(); - }, - - _createElement: function(element) { - return $(element); - }, - - _setShortcuts: function () { - var that = this; - window.addEventListener("cut", function (e) { - if (document.activeElement == document.body) { - that.copyCriteria(); - that.clearCriteria(); - e.preventDefault(); - } - }); - window.addEventListener("copy", function (e) { - if (document.activeElement == document.body) { - that.copyCriteria(); - e.preventDefault(); - } - }); - window.addEventListener("paste", function (e) { - if (document.activeElement == document.body) { - that.pasteCriteria(); - e.preventDefault(); - } - }); - }, - - _handleShortcuts: function(e) { - if (document.activeElement === document.body) { - if (e.keyCode == 46) { - this.clearCriteria(); - e.preventDefault(); - } else if (e.ctrlKey || e.metaKey) { - if (e.keyCode == 90) { - if (e.shiftKey) { - this.redo(); - } else { - this.undo(); - } - e.preventDefault(); - } else if (e.keyCode == 89) { - this.redo(); - e.preventDefault(); - } - } - } - }, - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.loadPlate = function(THIS) { - // Methods which look after data changes and stack up accordingly - // Remember THIS points to plateLayOutWidget and 'this' points to engine - return { - - getPlates: function (data) { - //sanitize input - var derivative = {}; - for (var index in data.derivative) { - var well = data.derivative[index]; - derivative[index] = this.sanitizeWell(well); - } - - var checkboxes = data.checkboxes || []; - var selection = this.sanitizeAreas(data.selectedAreas, data.focalWell); - - var sanitized = { - "derivative": derivative, - "checkboxes": checkboxes, - "selectedAreas": selection.selectedAreas, - "focalWell": selection.focalWell - }; - - this.setData(sanitized); - }, - - sanitizeAreas: function (selectedAreas, focalWell) { - var that = this; - var rows = this.dimensions.rows; - var cols = this.dimensions.cols; - - if (!selectedAreas) { - selectedAreas = []; - } - if (selectedAreas.length) { - selectedAreas = selectedAreas.map(function (area) { - return { - minCol: that._coordIndex(Math.min(area.minCol, area.maxCol), cols), - minRow: that._coordIndex(Math.min(area.minRow, area.maxRow), rows), - maxCol: that._coordIndex(Math.max(area.minCol, area.maxCol), cols), - maxRow: that._coordIndex(Math.max(area.minRow, area.maxRow), rows) - }; - }); - var area = selectedAreas[selectedAreas.length - 1]; - if (focalWell && !this._wellInArea(focalWell, area)) { - focalWell = null; - } - if (!focalWell) { - focalWell = { - row: area.minRow, - col: area.minCol - }; - } - } else { - if (!focalWell) { - focalWell = { - row: 0, - col: 0 - }; - } - selectedAreas = [this._wellToArea(focalWell)]; - } - return { - selectedAreas: selectedAreas, - focalWell: focalWell - }; - }, - - sanitizeWell: function (well) { - var newWell = {}; - for (var i = 0; i < this.fieldList.length; i++) { - var field = this.fieldList[i]; - newWell[field.id] = field.parseValue(well[field.id]); - } - return newWell; - }, - - setData: function(data) { - this.engine.derivative = $.extend(true, {}, data.derivative); - this.setCheckboxes(data.checkboxes); - this.setSelection(data.selectedAreas, data.focalWell); - this._colorMixer(); - this.decideSelectedFields(); - this.mainFabricCanvas.renderAll(); - }, - - } - } -})(jQuery, fabric); -var GET_PLATES = 'getPlates'; -var IS_READ_ONLY = 'isReadOnly'; -var IS_DISABLE_ADD_DELETE_WELL = 'isDisableAddDeleteWell'; -var GET_SELECTED_OBJECT = 'getSelectedObject'; -var SETSELECTEDWELL = 'setSelectedWell'; -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.overlay = function() { - // overlay holds all the methods to put the part just above the canvas which contains all those - // 'completion percentage' annd 'copy Criteria' button etc ... - return { - - _createOverLay: function() { - - var that = this; - this.overLayTextContainer = this._createElement("<div></div>").addClass("plate-setup-overlay-text-container"); - this.overLayTextContainer.text("Completion Percentage:"); - this.overLayContainer.append(this.overLayTextContainer); - this.overLayButtonContainer = this._createElement("<div></div>").addClass("plate-setup-overlay-button-container"); - this.overLayContainer.append(this.overLayButtonContainer); - - this.clearCriteriaButton = this._createElement("<button />").addClass("plate-setup-button"); - this.clearCriteriaButton.text("Clear"); - this.overLayButtonContainer.append(this.clearCriteriaButton); - - this.clearCriteriaButton.click(function(evt) { - that.clearCriteria(); - }); - - this.copyCriteriaButton = this._createElement("<button />").addClass("plate-setup-button"); - this.copyCriteriaButton.text("Copy"); - this.overLayButtonContainer.append(this.copyCriteriaButton); - - this.copyCriteriaButton.click(function(evt) { - that.copyCriteria(); - }); - - this.pasteCriteriaButton = this._createElement("<button />").addClass("plate-setup-button"); - this.pasteCriteriaButton.text("Paste"); - this.overLayButtonContainer.append(this.pasteCriteriaButton); - - this.pasteCriteriaButton.click(function(evt) { - that.pasteCriteria(); - }); - - this.undoButton = this._createElement("<button />").addClass("plate-setup-button"); - this.undoButton.text("Undo"); - this.overLayButtonContainer.append(this.undoButton); - - this.undoButton.click(function(evt) { - that.undo(); - }); - - this.redoButton = this._createElement("<button />").addClass("plate-setup-button"); - this.redoButton.text("Redo"); - this.overLayButtonContainer.append(this.redoButton); - - this.redoButton.click(function(evt) { - that.redo(); - }); - - }, - - clearCriteria: function() { - if (this.allSelectedObjects) { - var noOfSelectedObjects = this.allSelectedObjects.length; - var hasWellUpdate = false; - for (var objectIndex = 0; objectIndex < noOfSelectedObjects; objectIndex++) { - var tile = this.allSelectedObjects[objectIndex]; - if (tile.index in this.engine.derivative) { - // handling for clearing well when not allowed to add or delete wells - if (this.emptyWellWithDefaultVal && this.disableAddDeleteWell) { - var well = JSON.parse(JSON.stringify(this.defaultWell)); - var defaultValue = this.emptyWellWithDefaultVal; - for (var key in defaultValue){ - if (key in well) { - well[key] = defaultValue[key]; - this._applyFieldData(key, defaultValue[key]); - } else { - console.log("Well does not contain key: " + key + ", please contact support"); - } - } - this.engine.derivative[tile.index] = well; - } else { - delete this.engine.derivative[tile.index]; - } - hasWellUpdate = true; - } - } - if (hasWellUpdate){ - this.derivativeChange(); - } - - this._colorMixer(); - this.decideSelectedFields(); - } else { - alert("Please select any well"); - } - }, - - copyCriteria: function() { - if (this.allSelectedObjects) { - var wells = this._getSelectedWells(); - this.commonWell = this._getCommonFields(wells); - } else { - alert("Please select any well."); - } - }, - - pasteCriteria: function() { - if (this.commonWell) { - this._addAllData(this.commonWell); - this.decideSelectedFields(); - this.mainFabricCanvas.renderAll(); - } - } - }; - } -})(jQuery, fabric); -$.widget("DNA.plateLayOut", { - - plateLayOutWidget: {}, - - options: { - value: 0 - }, - - allTiles: [], // All tiles containes all thise circles in the canvas - - addressToLoc: function (layoutAddress) { - var m = /^([A-Z]+)(\d+)$/.exec(layoutAddress.trim().toUpperCase()) - if (m) { - var row_v = m[1]; - var col = parseInt(m[2])-1; - var row; - for (var i = 0; i < row_v.length; i++) { - var c = row_v.charCodeAt(i) - 65; - if (i) { - row += 1; - row *= 26; - row += c ; - } else { - row = c; - } - } - return { - r: row, - c: col - }; - } else { - throw layoutAddress + " not a proper layout address"; - } - }, - - locToIndex: function (loc, dimensions) { - if (!dimensions) { - dimensions = this.dimensions; - } - if (loc.r < 0) { - t - } - if (!(loc.r >= 0 && loc.r < dimensions.rows)) { - throw "Row index " + (loc.r + 1) + " invalid"; - } - if (!(loc.c >= 0 && loc.c < dimensions.cols)) { - throw "Column index " + (loc.c + 1) + " invalid"; - } - return loc.r*dimensions.cols + loc.c; - }, - - addressToIndex: function (layoutAddress, dimensions) { - var loc = this.addressToLoc(layoutAddress); - return this.locToIndex(loc, dimensions); - }, - - _rowKey: function (i) { - var c1 = i % 26; - var c2 = (i - c1) / 26; - var code = String.fromCharCode(65 + c1); - if (c2 > 0) { - code = String.fromCharCode(64 + c2) + code; - } - return code; - }, - - indexToLoc: function (index, dimensions) { - if (!dimensions) { - dimensions = this.dimensions; - } - - if (index >= dimensions.rows * dimensions.cols) { - throw "Index too high: " + index.toString(10); - } - var loc = {}; - loc.c = index % dimensions.cols; - loc.r = (index - loc.c) / dimensions.cols; - - return loc; - }, - - locToAddress: function (loc) { - return this._rowKey(loc.r) + (loc.c + 1).toString(10); - }, - - indexToAddress: function (index, dimensions) { - var loc = this.indexToLoc(index, dimensions); - return this.locToAddress(loc); - }, - - getDimensions: function () { - return $.extend(true, {}, this.dimensions); - }, - - _create: function() { - var rows = parseInt(this.options.numRows || 8); - var cols = parseInt(this.options.numCols || 12); - this.dimensions = { - rows: rows, - cols: cols - }; - this.rowIndex = []; - for (var i = 0; i < rows; i++) { - this.rowIndex.push(this._rowKey(i)); - } - - this.target = (this.element[0].id) ? "#" + this.element[0].id : "." + this.element[0].className; - - // Import classes from other files.. Here we import it using extend and add it to this - // object. internally we add to widget.DNA.getPlates.prototype. - // Helpers are methods which return other methods and objects. - // add Objects to plateLayOutWidget and it will be added to this object. - // set read only well - if (this.options.readOnly){ - this.isReadOnly(true); - } - - for (var component in plateLayOutWidget) { - // Incase some properties has to initialize with data from options hash, - // we provide it sending this object. - $.extend(this, new plateLayOutWidget[component](this)); - } - - this.imgSrc = this.options.imgSrc || "assets"; - - this._createInterface(); - - this._trigger("created", null, this); - - return this; - }, - - _init: function() { - // This is invoked when the user use the plugin after _create is called. - // The point is _create is invoked for the very first time and for all other - // times _init is used. - }, - - addData: function() { - alert("wow this is good"); - }, - - // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}} - getTextDerivative: function(wellsData) { - var textDerivative = {}; - var fieldMap = this.fieldMap; - for (var idx in wellsData){ - var textValWell = {}; - var textFieldIdWell = {}; - var curWellData = wellsData[idx]; - for (var fieldId in curWellData){ - if (fieldId in this.fieldMap){ - var field = this.fieldMap[fieldId]; - var textVal = field.parseText(curWellData[fieldId]); - textFieldIdWell[field.name] = textVal; - textValWell[fieldId] = textVal; - } else { - // do not convert if not a field (ex: layout_address) - textFieldIdWell[fieldId] = curWellData[fieldId]; - textValWell[fieldId] = curWellData[fieldId]; - } - } - textDerivative[idx] = { - textVal: textValWell, - textFieldVal: textFieldIdWell - }; - } - - return textDerivative; - }, - - // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}} - getWellsDifferences: function(wellsData) { - return this.getDifferentWellsVals(wellsData); - }, - - setFieldsDisabled: function(flag){ - this.fieldList.forEach(function(field){ - field.disabled(flag); - }); - }, - - isReadOnly: function(flag){ - if (flag){ - this.readOnly = true; - } else { - this.readOnly = false; - } - this.readOnlyHandler(); - }, - - readOnlyHandler: function(){ - if (this.readOnly){ - this.overLayButtonContainer.css("display", "none"); - $('.multiple-field-manage-delete-button').css("display", "none"); - this.setFieldsDisabled(true); - } else { - this.overLayButtonContainer.css("display", "flex"); - $('.multiple-field-manage-delete-button').css("display", "none"); - if (!this.disableAddDeleteWell) { - this.setFieldsDisabled(false); - } - } - }, - - disableAddDeleteWell: null, - // column_with_default_val will be used to determine empty wells, format: {field_name: default_val} - isDisableAddDeleteWell: function(flag, column_with_default_val){ - if (flag){ - this.disableAddDeleteWell = true; - this.addressAllowToEdit = this.getWellSetAddressWithData(); - // configure undo redo action - this.actionPointer = 0; - this.undoRedoArray = []; - this.undoRedoArray.push(this.createObject()); - if (column_with_default_val) { - this.emptyWellWithDefaultVal = column_with_default_val; - } - } else { - this.disableAddDeleteWell = false; - this.setFieldsDisabled(false); - this.emptyWellWithDefaultVal = null; - } - this._fabricEvents(); - }, - - getSelectedObject: function() { - var selectedAddress = []; - for (var i = 0; i < this.allSelectedObjects.length; i++){ - selectedAddress.push(this.allSelectedObjects[i].address); - } - var selectedObjects = {}; - var derivative = this.engine.derivative; - for (var loc in derivative){ - var address = this.indexToAddress(loc); - if (selectedAddress.indexOf(address) >= 0) { - selectedObjects[address] = derivative[loc]; - } - } - return selectedObjects; - }, - - getSelectedIndex: function() { - return this.allSelectedObjects.map(function(selectedObj){ - return that.addressToIndex(selectedObj.address) - }); - }, - - getSelectedAddress: function() { - return this.allSelectedObjects.map(function(selectedObj){ - return selectedObj.address; - }); - }, - - setSelectedWell: function(addressList) { - var areas = []; - var minRow = 999; - var locMap = {}; - for (var id = 0; id < addressList.length; id++){ - var wellIdx = this.addressToIndex(addressList[id]); - var loc = this.indexToLoc(wellIdx); - areas.push({ - minCol: loc.c, - minRow: loc.r, - maxCol: loc.c, - maxRow: loc.r - }); - if (loc.r <= minRow) { - minRow = loc.r; - if (loc.r in locMap) { - locMap[loc.r].push(loc.c); - } else { - locMap[loc.r] = [loc.c]; - } - } - } - var focalWell = { - row: minRow, - col: Math.min.apply(null, locMap[minRow]) - }; - - this.setSelection(areas, focalWell); - this.decideSelectedFields(); - this.mainFabricCanvas.renderAll(); - } - -}); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.preset = function(me) { - // All the preset action goes here - return { - - presets: [], - - _placePresetTabs: function() { - var presets = this.options.attributes.presets; - - if (presets && presets.length) { - this.wellAttrContainer = this._createElement("<div></div>").addClass("plate-setup-well-attr-container") - .text("Checkbox presets"); - this.tabContainer.append(this.wellAttrContainer); - - this.presetTabContainer = this._createElement("<div></div>").addClass("plate-setup-preset-container"); - this.tabContainer.append(this.presetTabContainer); - - for (var i = 0; i < presets.length; i++) { - var preset = presets[i]; - var divText = this._createElement("<div></div>").addClass("plate-setup-prest-tab-div") - .text(preset.title); - - var presetButton = this._createElement("<div></div>").addClass("plate-setup-prest-tab") - .data("preset", preset.fields).append(divText); - this.presetTabContainer.append(presetButton); - - var that = this; - presetButton.click(function() { - var preset = $(this); - that._selectPreset(preset); - }); - this.presets.push(presetButton); - } - } - }, - - _clearPresetSelection: function() { - for (var j = 0; j < this.presets.length; j++) { - var p = this.presets[j]; - p.removeClass("plate-setup-prest-tab-selected") - .addClass("plate-setup-prest-tab"); - } - }, - - _selectPreset: function (preset) { - this.setCheckboxes(preset.data("preset")); - preset.removeClass("plate-setup-prest-tab") - .addClass("plate-setup-prest-tab-selected"); - }, - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.tabs = function() { - // Tabs crete and manage tabs at the right side of the canvas. - return { - - allTabs: [], - - defaultWell: {}, - - allDataTabs: [], // To hold all the tab contents. this contains all the tabs and its elements and elements - // Settings as a whole. its very usefull, when we have units for a specific field. - // it goes like tabs-> individual field-> units and checkbox - - _createTabAtRight: function() { - this.tabContainer = this._createElement("<div></div>").addClass("plate-setup-tab-container"); - $(this.topRight).append(this.tabContainer); - }, - - _createTabs: function() { - // this could be done using z-index. just imagine few cards stacked up. - // Check if options has tab data. - // Originally we will be pulling tab data from developer. - // Now we are building upon dummy data. - this.tabHead = this._createElement("<div></div>").addClass("plate-setup-tab-head"); - $(this.tabContainer).append(this.tabHead); - - var tabData = this.options.attributes.tabs; - var that = this; - - tabData.forEach(function (tab, tabIndex) { - that.allTabs[tabIndex] = that._createElement("<div></div>").addClass("plate-setup-tab"); - $(that.allTabs[tabIndex]).data("index", tabIndex) - .text(tab.name); - - $(that.allTabs[tabIndex]).click(function() { - that._tabClickHandler(this); - }); - - $(that.tabHead).append(that.allTabs[tabIndex]); - }); - - this.tabDataContainer = this._createElement("<div></div>").addClass("plate-setup-tab-data-container"); - $(this.tabContainer).append(this.tabDataContainer); - - this._addDataTabs(tabData); - - $(this.allTabs[0]).click(); - - this._addTabData(); - }, - - _tabClickHandler: function(clickedTab) { - - if (this.selectedTab) { - $(this.selectedTab).removeClass("plate-setup-tab-selected") - .addClass("plate-setup-tab"); - - var previouslyClickedTabIndex = $(this.selectedTab).data("index"); - $(this.allDataTabs[previouslyClickedTabIndex]).css("z-index", 0); - this.readOnlyHandler(); - } - - $(clickedTab).addClass("plate-setup-tab-selected"); - - this.selectedTab = clickedTab; - - var clickedTabIndex = $(clickedTab).data("index"); - $(this.allDataTabs[clickedTabIndex]).css("z-index", 1000); - }, - - _addDataTabs: function(tabs) { - - var tabIndex = 0; - - for (var tabData in tabs) { - this.allDataTabs[tabIndex++] = this._createElement("<div></div>").addClass("plate-setup-data-div") - .css("z-index", 0); - $(this.tabDataContainer).append(this.allDataTabs[tabIndex - 1]); - } - } - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.undoRedoManager = function(THIS) { - - return { - - undoRedoArray: [], - - actionPointer: null, - - addToUndoRedo: function(data) { - - if (this.actionPointer != null) { - var i = this.actionPointer + 1; - if (i < this.undoRedoArray.length) { - this.undoRedoArray.splice(i, this.undoRedoArray.length - i); - } - } - this.actionPointer = null; - this.undoRedoArray.push($.extend(true, {}, data)); - }, - - _configureUndoRedoArray: function() { - - var data = { - checkboxes: [], - derivative: {}, - selectedAreas: [{ - minRow: 0, - minCol: 0, - maxRow: 0, - maxCol: 0 - }], - focalWell: { - row: 0, - col: 0 - } - }; - - this.undoRedoArray = []; - this.actionPointer = null; - this.undoRedoArray.push($.extend({}, data)); - }, - - undo: function() { - console.log("undo"); - return this.shiftUndoRedo(-1); - }, - - redo: function() { - console.log("redo"); - return this.shiftUndoRedo(1); - }, - - shiftUndoRedo: function (pointerDiff) { - var pointer = this.actionPointer; - if (pointer == null) { - pointer = this.undoRedoArray.length - 1; - } - pointer += pointerDiff; - return this.setUndoRedo(pointer); - }, - - setUndoRedo: function (pointer) { - if (pointer < 0) { - return false; - } - if (pointer >= this.undoRedoArray.length) { - return false; - } - this.undoRedoActive = true; - this.setData(this.undoRedoArray[pointer]); - this.actionPointer = pointer; - this.undoRedoActive = false; - this.derivativeChange(); - return true; - } - } - }; - -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.wellArea = function(fabric) { - - return { - - _areasToTiles: function(areas) { - //Convert areas to tiles - var cols = this.dimensions.cols; - var that = this; - return areas.reduce(function(tiles, area) { - if (area) { - for (var r = area.minRow; r <= area.maxRow; r++) { - for (var c = area.minCol; c <= area.maxCol; c++) { - var tile = that.allTiles[c + cols * r]; - if (tiles.indexOf(tile) < 0) { - if (that.disableAddDeleteWell){ - if(that.addressAllowToEdit.indexOf(tile.address) >= 0){ - tiles.push(tile); - } - } else { - tiles.push(tile); - } - } - } - } - } - return tiles; - }, []); - }, - - _encodeArea: function(area) { - //Encode area as string - if ((area.minRow == area.maxRow) && (area.minCol == area.maxCol)) { - return this.rowIndex[area.minRow] + area.minCol.toString(10); - } else { - return this.rowIndex[area.minRow] + area.minCol.toString(10) + ":" + this.rowIndex[area.maxRow] + area.maxCol.toString(10); - } - }, - - _encodeAreas: function(areas) { - //Encode an array of areas as a string - var that = this; - return areas.map(function(area) { - return that._encodeArea(area); - }).join(","); - }, - - _decodeWell: function(wellAddress) { - var that = this; - var adRx = new RegExp("^\\s*(" + that.rowIndex.join("|") + ")(\\d+)\\s*$") - var rcRx = /^\s*R(\d+)C(\d+)\s*$/i; - - var match; - match = wellAddress.match(adRx); - if (match) { - var row = that.rowIndex.indexOf(match[1]); - if (row >= 0) { - return { - row: row, - col: parseInt(match[2]) - 1 - }; - } - } - match = wellAddress.match(rcRx); - if (match) { - return { - row: parseInt(match[1]) - 1, - col: parseInt(match[2]) - 1 - }; - } - - throw "Invalid well address: " + wellAddress; - }, - - _decodeArea: function(areaAddress) { - //Decode single area as string - var that = this; - var wells = areaAddress.split(":").map(function(wellAddress) { - return that._decodeWell(wellAddress); - }) - if (wells.length == 1) { - return { - minRow: wells[0].row, - minCol: wells[0].col, - maxRow: wells[0].row, - maxCol: wells[0].col - } - } else if (wells.length == 2) { - var minRow = Math.min(wells[0].row, wells[1].row) - return { - minRow: Math.min(wells[0].row, wells[1].row), - minCol: Math.min(wells[0].col, wells[1].col), - maxRow: Math.max(wells[0].row, wells[1].row), - maxCol: Math.max(wells[0].col, wells[1].col) - } - } else { - throw "Invalid address: " + areaAddress; - } - }, - - _decodeAreas: function(areasAddress) { - //Decode single area as string - var that = this; - return areasAddress.split(",").map(function(areaAddress) { - return that._decodeArea(areaAddress); - }); - }, - - _wellToArea: function(well) { - //Convert a well to an area - return { - minCol: well.col, - minRow: well.row, - maxCol: well.col, - maxRow: well.row - } - }, - - _wellInArea: function(well, area) { - //Determine if a well lies within an area - return well.row >= area.minRow && well.row <= area.maxRow && well.col >= area.minCol && well.col <= area.maxCol; - }, - - _coordsToRect: function(startCoords, endCoords) { - //Convert two XY coords to a bounding box - var left = Math.min(startCoords.x, endCoords.x); - var top = Math.min(startCoords.y, endCoords.y); - var height = Math.abs(endCoords.y - startCoords.y); - var width = Math.abs(endCoords.x - startCoords.x); - return { - top: top, - left: left, - height: height, - width: width - }; - }, - - _coordIndex: function(v, count) { - var i; - if (v < 0) { - i = 0; - } else if (v >= count) { - i = count - 1; - } else { - i = Math.floor(v); - } - return i; - }, - - _coordsToWell: function(coord) { - //Convert a coordinate to a well - var cols = this.dimensions.cols; - var rows = this.dimensions.rows; - - var w = this.sizes.spacing; - var m = this.sizes.label_spacing; - - var x = (coord.x - m) / w; - var y = (coord.y - m) / w; - - var row = this._coordIndex(y, rows); - var col = this._coordIndex(x, cols); - - return { - row: row, - col: col, - }; - }, - - _wellToCoords: function(well, center) { - //Convert a well to a coordinate - var w = this.sizes.spacing; - var m = this.sizes.label_spacing; - var x = well.col * w + m; - var y = well.row * w + m; - if (center) { - var hw = w/2; - x = x + hw; - y = y + hw; - } - - return { - x: x, - y: y - }; - }, - - _areaToRect: function(area) { - //Convert area to rectangle - var rows = area.maxRow - area.minRow + 1; - var cols = area.maxCol - area.minCol + 1; - - var w = this.sizes.spacing; - var m = this.sizes.label_spacing; - - return { - top: area.minRow * w + m, - left: area.minCol * w + m, - height: rows * w, - width: cols * w - } - }, - - _rectToArea: function(rect) { - //Convert a rectangular region to an area - var rows = this.dimensions.rows; - var cols = this.dimensions.cols; - - var w = this.sizes.spacing; - var m = this.sizes.label_spacing; - - var left = (rect.left - m) / w; - var top = (rect.top - m) / w; - var height = rect.height / w; - var width = rect.width / w; - var right = left + width; - var bottom = top + height; - - //select whole row - if (right < 0) { - right = cols; - } - if (left >= cols) { - left = 0; - } - //select whole col - if (bottom < 0) { - bottom = rows; - } - if (top <= 0) { - top = 0; - } - - return { - minCol: this._coordIndex(left, cols), - minRow: this._coordIndex(top, rows), - maxCol: this._coordIndex(right, cols), - maxRow: this._coordIndex(bottom, rows) - }; - } - - } - } -})(jQuery, fabric); \ No newline at end of file diff --git a/dist/js/plate-map.min.js b/dist/js/plate-map.min.js deleted file mode 100755 index e20d70f..0000000 --- a/dist/js/plate-map.min.js +++ /dev/null @@ -1,2 +0,0 @@ -var plateLayOutWidget=plateLayOutWidget||{};!function(u,e){plateLayOutWidget.addDataOnChange=function(){return{_addAllData:function(e){if(this.allSelectedObjects)for(var t=this.allSelectedObjects.length,i=[],a=0;a<t;a++){var n,l=this.allSelectedObjects[a];l.index in this.engine.derivative?n=this.engine.derivative[l.index]:(n=u.extend(!0,{},this.defaultWell),this.engine.derivative[l.index]=n);var s=this.processWellData(e,n,t,i);if(i=s.wells,n=s.well,this.engine.wellEmpty(n))if(this.emptyWellWithDefaultVal&&this.disableAddDeleteWell){var r=JSON.parse(JSON.stringify(n)),o=this.emptyWellWithDefaultVal;for(var d in o)d in r&&(r[d]=o[d],this._applyFieldData(d,o[d]));this.engine.derivative[l.index]=r}else delete this.engine.derivative[l.index]}this._getAllMultipleVal(i),this.applyFieldWarning(i),this._colorMixer(),this.derivativeChange()},processWellData:function(e,t,i,a){for(var n in a||(a=[]),e){var l;if(void 0!==e[n]&&null!==e[n])if(e[n].multi){var s=e[n],r=t[n],o=this._getMultiData(r,s,n,i);l=JSON.parse(JSON.stringify(o))}else l=JSON.parse(JSON.stringify(e[n]));else l=JSON.parse(JSON.stringify(e[n]));t[n]=l,a.push(t)}return{well:t,wells:a}},_getMultiData:function(e,t,i,a){var n=t.added,l=t.removed;if(n)if(e)if(n.value){var s=!0;for(var r in e){e[r][i].toString()===n.id.toString()&&(s=!1,e=e.map(function(e){if(e[i].toString()===n.id.toString())for(var t in e)t in n.value&&t!==i&&(1===a?e[t]=n.value[t]:n.value[t]&&(e[t]=n.value[t]));return e}))}s&&e.push(n.value)}else e.indexOf(n)<0&&e.push(n);else e=[],n.value?e.push(n.value):n&&e.push(n);var o,d=function(e,t){var i=[];for(var a in e)parseInt(a)!==parseInt(t)&&i.push(e[a]);return i};if(l)if(l.value){for(var r in e){e[r][i].toString()===l.id.toString()&&(o=r)}e=d(e,o)}else e&&0<=(o=e.indexOf(l))&&(e=d(e,o));return e&&0==e.length&&(e=null),e},_colorMixer:function(){if(!this.undoRedoActive){var e=this.createObject();this.addToUndoRedo(e)}this.engine.searchAndStack(),this.engine.applyColors(),this.mainFabricCanvas.renderAll()},derivativeChange:function(){this._trigger("updateWells",null,this.createObject())},createObject:function(){return{derivative:u.extend(!0,{},this.engine.derivative),checkboxes:this.globalSelectedAttributes.slice(),selectedAreas:this.selectedAreas.slice(),focalWell:this.focalWell,requiredField:this.requiredField}}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};jQuery,fabric,plateLayOutWidget.addDataToFields=function(){return{_addDataToTabFields:function(e){for(var t in e)this._applyFieldData(t,e[t])},_applyFieldData:function(e,t){this.fieldMap[e].setValue(t)}}};plateLayOutWidget=plateLayOutWidget||{};!function(u,e){plateLayOutWidget.addTabData=function(){return{fieldList:[],fieldMap:{},autoId:1,_addTabData:function(){var e=this.options.attributes.tabs,r=this;this.requiredField=[];var o=[];e.forEach(function(e,t){if(e.fields){var i=e.fields,a=[];for(var n in i){var l,s=i[n];s.id||(s.id="Auto"+r.autoId++,console.log("Field autoassigned id "+s.id)),s.type||(s.type="text",console.log("Field "+s.id+" autoassigned type "+s.type)),"multiplex"===s.type?(l=r._makeMultiplexField(s,t,a),o.push(l)):(l=r._makeRegularField(s,t,a,!0),"multiselect"===s.type&&o.push(l))}r.allDataTabs[t].fields=a}else console.log("unknown format in field initialization")}),r.multipleFieldList=o},_makeSubField:function(e,t,i){var a=this;e.id||(e.id="Auto"+a.autoId++,console.log("Field autoassigned id "+e.id)),e.type||(e.type="text",console.log("Field "+e.id+" autoassigned type "+e.type));var n=a._createElement("<div></div>").addClass("plate-setup-tab-default-field"),l=a._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"),s=a._createElement("<div></div>").addClass("plate-setup-tab-field-right-side"),r=a._createElement("<div></div>").addClass("plate-setup-tab-name").text(e.name),o=a._createElement("<div></div>").addClass("plate-setup-tab-field-container");u(s).append(r),u(s).append(o),u(n).append(l),u(n).append(s),u(a.allDataTabs[t]).append(n);var d={id:e.id,name:e.name,root:n,data:e,required:e.required||!1};return i.push(d),a.fieldMap[e.id]=d},_makeRegularField:function(e,t,i,a){var n=this,l=n._createElement("<div></div>").addClass("plate-setup-tab-default-field"),s=n._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"),r=n._createElement("<div></div>").addClass("plate-setup-tab-field-right-side "),o=n._createElement("<div></div>").addClass("plate-setup-tab-name").text(e.name),d=n._createElement("<div></div>").addClass("plate-setup-tab-field-container");r.append(o),r.append(d),l.append(s),l.append(r),n.allDataTabs[t].append(l);var u={id:e.id,name:e.name,root:l,data:e,required:e.required};return u.required&&n.requiredField.push(u.id),i.push(u),n.fieldList.push(u),n.fieldMap[u.id]=u,a&&n._addCheckBox(u),n._createField(u),u.onChange=function(){var e=u.getValue(),t={};t[u.id]=e,n._addAllData(t)},u},_makeMultiplexField:function(e,t,i){var a=this,n=a._createElement("<div></div>").addClass("plate-setup-tab-default-field"),l=a._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"),s=a._createElement("<div></div>").addClass("plate-setup-tab-field-right-side "),r=a._createElement("<div></div>").addClass("plate-setup-tab-name").text(e.name),o=a._createElement("<div></div>").addClass("plate-setup-tab-field-container");s.append(r),s.append(o),n.append(l),n.append(s),a.allDataTabs[t].append(n);var d={id:e.id,name:e.name,root:n,data:e,required:e.required};i.push(d),a.fieldList.push(d),a.fieldMap[e.id]=d;var u=[],c=[];for(var f in e.multiplexFields){var h=e.multiplexFields[f],p=a._makeSubField(h,t,i);u.push(p),h.required&&c.push(p.id)}return(d.required||c.length)&&this.requiredField.push({multiplexId:d.id,subFields:c}),d.subFieldList=u,a._createField(d),a._addCheckBox(d),u.forEach(function(s){s.mainMultiplexField=d,i.push(s),a._createField(s),a._addCheckBox(s),delete a.defaultWell[s.id],s.onChange=function(){var t=s.getValue(),i=s.mainMultiplexField,a=i.singleSelectValue(),e={};e[i.id]=a,e[s.id]=t;var n={id:a,value:e};d._changeMultiFieldValue(n,null);var l=i.detailData;null!==l&&(a=i.singleSelectValue(),l=l.map(function(e){return e[i.id]===a&&(e[s.id]=t),e})),i.detailData=l}}),d.getValue=function(){var e=d.input.select2("data");return e.length?e.map(function(e){return e.id}):null},d}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(s,e){plateLayOutWidget.addWarningMsg=function(){return{fieldWarningMsg:function(e,t,i){var a="fieldWarning"+e.id,n=s("<span>").html(this._assets.warningImg).attr("id",a).addClass("plate-field-warning-image");if(i){if(e.root.find("#"+a).length<=0){e.root.find(".plate-setup-tab-name").text(" "+e.name),e.root.find(".plate-setup-tab-name").prepend(n);var l=s("<div/>").addClass("pop-out-text");l.text(t),e.root.find(".plate-setup-tab-name").append(l),s("#"+a).hover(function(e){l[0].style.display="flex"},function(){l.hide()})}}else 0<e.root.find("#"+a).length&&(e.root.find(".plate-setup-tab-name").text(e.name),s("#"+a).remove())},removeWarningMsg:function(e,t,i){var a="fieldWarning"+e.id,n=s("<span>").html(this._assets.warningImg).attr("id",a).addClass("plate-field-warning-image");if(i){e.root.find(".plate-setup-tab-name").append(n);var l=s("<div/>").addClass("pop-out-text");l.text(t),e.root.find(".plate-setup-tab-name").append(l),s("#"+a).hover(function(e){l[0].style.display="inline-block"},function(){l.hide()})}else s("#"+a).remove(),0<e.root.find("#"+a).length&&s("#"+a).remove()},applyFieldWarning:function(e){var i=this,a={};i.fieldList.forEach(function(e){a[e.id]=[]}),e.forEach(function(e){if(!i.engine.wellEmpty(e))for(var t in a)t in e?a[t].push(e[t]):a[t].push(null)});for(var t=0;t<i.fieldList.length;t++){var n=i.fieldList[t];if(n.applyMultiplexSubFieldColor)n.applyMultiplexSubFieldColor(a[n.id]);else if(n.required){var l=!1;a[n.id].forEach(function(e){e instanceof Array?0===e.length&&(l=!0):null===e&&(l=!0)}),i.fieldWarningMsg(n,"required field",l)}}}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(d,e){plateLayOutWidget.bottomTable=function(){return{_bottomScreen:function(){this.bottomContainer=this._createElement("<div></div>").addClass("plate-setup-bottom-container"),this.bottomTableContainer=this._createElement("<div></div>").addClass("plate-setup-bottom-table-container"),this.bottomTable=this._createElement("<table></table>").addClass("plate-setup-bottom-table"),this.bottomTableContainer.append(this.bottomTable),this.bottomContainer.append(this.bottomTableContainer),this.container.append(this.bottomContainer)},addBottomTableHeadings:function(){this.bottomRow=this._createElement("<tr></tr>");var e=this._createElement("<th></th>").text("Group");this.bottomRow.prepend(e),this.bottomTable.empty(),this.bottomTable.append(this.bottomRow),this.rowCounter=1;for(var t=0;t<this.globalSelectedAttributes.length;t++){var i=this.globalSelectedAttributes[t],a=this.fieldMap[i];e=this._createElement("<th></th>").text(a.name);this.bottomRow.append(e),this.rowCounter=this.rowCounter+1}this.adjustFieldWidth(this.bottomRow)},tileAttrText:function(e,t){var i=this.engine.derivative[e.index];return this.fieldMap[t].getText(i[t])},addBottomTableRow:function(e,i){var a=this,t=this.allTiles[i[0]],n=this._createElement("<tr></tr>"),l=this._createElement("<td></td>").addClass("plate-setup-bottom-id"),s=this._createElement("<button/>");s.addClass("plate-setup-color-text"),s.text(e),l.append(s),s.click(function(e){var t=i.map(function(e){return a.indexToAddress(e)});e.ctrlKey&&a.getSelectedAddress().forEach(function(e){t.indexOf(e)<0&&t.push(e)}),a.setSelectedWell(t),a._trigger("selectedWells",null,{selectedAddress:a.getSelectedAddress()})}),0<e&&(e=(e-1)%(this.colorPairs.length-1)+1);var r=this.colorPairs[e];l.css("background","linear-gradient(to right, "+r[0]+" , "+r[1]+")"),n.append(l);for(var o=0;o<this.globalSelectedAttributes.length;o++){var d=this.globalSelectedAttributes[o],u=this.tileAttrText(t,d),c=this._createElement("<td></td>").text(u);n.append(c)}this.bottomTable.append(n),this.adjustFieldWidth(n)},bottomForFirstTime:function(){this.addBottomTableHeadings();var e=this._createElement("<tr></tr>"),t=this.colorPairs[0],i=this._createElement("<td></td>");i.css("background","-webkit-linear-gradient(left, "+t[0]+" , "+t[1]+")"),e.append(i),this.bottomTable.append(e),this.createExportButton()},adjustFieldWidth:function(e){var t=this.rowCounter;1024<150*t&&e.css("width",152*t+"px")},downloadCSV:function(e,t){var i,a;i=new Blob([e],{type:"text/csv"}),(a=document.createElement("a")).download=t,a.href=window.URL.createObjectURL(i),a.style.display="none",document.body.appendChild(a),a.click()},exportData:function(e){var t=[],i=document.querySelectorAll("table tr"),a={},n=this.engine.stackUpWithColor,l=this.getDimensions(),s=this;for(var r in n)a[r]=n[r].map(function(e){return s.indexToAddress(e,l)});for(var o=0;o<i.length;o++){for(var d=[],u=i[o].querySelectorAll("td, th"),c=0;c<u.length;c++){var f="";if(u[c].innerText&&(f="csv"===e?'"'+u[c].innerText.replace(/"/g,'""')+'"':u[c].innerText),d.push(f),0===o&&0===c&&("csv"===e?d.push('"Location"'):"clipboard"===e&&d.push("Location")),0!==o&&0===c){var h="";a[parseInt(u[c].innerText)]&&("csv"===e?h='"'+a[parseInt(u[c].innerText)].join(",")+'"':"clipboard"===e&&(h=a[parseInt(u[c].innerText)].join(","))),d.push(h)}}"csv"===e?t.push(d.join(",")):"clipboard"===e&&t.push(d.join("\t"))}if("csv"===e)this.downloadCSV(t.join("\n"),"table.csv");else if("clipboard"===e)return t.join("\n")},createExportButton:function(){var e=this,t=d("<div>").addClass("plate-setup-bottom-control-container"),i=d("<div>").addClass("plate-setup-overlay-text-container");i.text("Color groups"),t.append(i);var a=d("<div>").addClass("plate-setup-overlay-bottom-button-container"),n=d("<button/>").addClass("plate-setup-button");function l(){n.text("Export CSV"),n[0].classList.remove("plate-setup-clicked-button"),n.addClass("plate-setup-button")}n.text("Export CSV"),a.append(n),n.click(function(){e.exportData("csv"),n.text("Exported"),n[0].classList.remove("plate-setup-button"),n.addClass("plate-setup-clicked-button"),setTimeout(l,3e3)});var s=d("<button/>").addClass("plate-setup-button");s.text("Copy To Clipboard"),a.append(s);var r=new ClipboardJS(s.get(0),{text:function(){return e.exportData("clipboard")}});function o(){s.text("Copy To Clipboard"),s[0].classList.remove("plate-setup-clicked-button"),s.addClass("plate-setup-button")}r.on("success",function(e){s.text("Copied as tab-delimited format"),s[0].classList.remove("plate-setup-button"),s.addClass("plate-setup-clicked-button"),setTimeout(o,3e3)}),r.on("error",function(e){s.text("Failed to copy table to clipboard: browser may be incompatible"),setTimeout(o,3e3)}),t.append(a),d(".plate-setup-bottom-container").prepend(t)}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(e,i){plateLayOutWidget.canvas=function(){return{allSelectedObjects:null,allPreviouslySelectedObjects:null,colorPointer:0,goldenRatio:.618033988749895,_createCanvas:function(){this.normalCanvas=this._createElement("<canvas>").attr("id","DNAcanvas"),e(this.canvasContainer).append(this.normalCanvas)},_initiateFabricCanvas:function(){var e=this.canvasContainer.width(),t=this.canvasContainer.height();this._setCanvasArea(e,t),this.mainFabricCanvas=new i.Canvas("DNAcanvas",{backgroundColor:"#f5f5f5",selection:!1,stateful:!1,hoverCursor:"pointer",renderOnAddRemove:!1}).setWidth(e).setHeight(t)}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(l,e){plateLayOutWidget.checkBox=function(){return{globalSelectedAttributes:[],_addCheckBox:function(e){var t=l("<span>").html(this._assets.dontImg).addClass("plate-setup-tab-check-box bg-light").data("clicked",!1);t.data("linkedFieldId",e.id),e.root.find(".plate-setup-tab-field-left-side").empty().append(t),this._applyCheckboxHandler(t),e.checkbox=t},_applyCheckboxHandler:function(e){var n=this;e.click(function(e,t){var i=l(this),a={};a[i.data("linkedFieldId")]=!i.data("clicked"),n.changeCheckboxes(a)})},changeSubFieldsCheckboxes:function(e,n){var l=this,s=[];return e.subFieldList.forEach(function(e){var t=e.checkbox,i=t.data("linkedFieldId"),a=t.data("clicked");i in n&&(a=Boolean(n[i])),t.data("clicked",a),a?(t.html(l._assets.doImg),s.push(e.id)):t.html(l._assets.dontImg)}),s},changeCheckboxes:function(e){for(var t=[],i={},a=0;a<this.fieldList.length;a++){var n=this.fieldList[a];if(n.checkbox){n.subFieldList&&(i[n.id]=this.changeSubFieldsCheckboxes(n,e));var l=n.checkbox,s=l.data("linkedFieldId"),r=l.data("clicked");s in e&&(r=Boolean(e[s])),l.data("clicked",r),r?(t.push(s),l.html(this._assets.doImg)):l.html(this._assets.dontImg)}}this.globalSelectedMultiplexSubfield=i,this.globalSelectedAttributes=t,this._clearPresetSelection(),this._colorMixer()},setSubFieldCheckboxes:function(e,n){var l=this,s=[];return e.subFieldList.forEach(function(e){var t=e.checkbox,i=t.data("linkedFieldId"),a=0<=n.indexOf(i);t.data("clicked",a),a?(t.html(l._assets.doImg),s.push(e.id)):t.html(l._assets.dontImg)}),s},setCheckboxes:function(e){e=e||[];for(var t=[],i={},a=0;a<this.fieldList.length;a++){var n=this.fieldList[a];if(n.checkbox){n.subFieldList&&(i[n.id]=this.setSubFieldCheckboxes(n,e));var l=n.checkbox,s=l.data("linkedFieldId"),r=0<=e.indexOf(s);l.data("clicked",r),r?(t.push(s),l.html(this._assets.doImg)):l.html(this._assets.dontImg)}}this.globalSelectedMultiplexSubfield=i,this.globalSelectedAttributes=t,this._clearPresetSelection(),this._colorMixer()}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};jQuery,fabric,plateLayOutWidget.colorManager=function(){return{colorPairs:[["#e6e6e6","#808080"],["#66e8ff","#0082c8"],["#ff7fb1","#e6194b"],["#a2ffb1","#3cb44b"],["#f784ff","#911eb4"],["#ffe897","#f58231"],["#6666ff","#0000FF"],["#ffff7f","#ffe119"],["#acffff","#46f0f0"],["#ff98ff","#f032e6"],["#ffffa2","#d2f53c"],["#ffffff","#fabebe"],["#66e6e6","#008080"],["#ffffff","#e6beff"],["#ffd48e","#aa6e28"],["#e66666","#800000"],["#ffffff","#aaffc3"],["#e6e666","#808000"],["#ffffff","#ffd8b1"],["#66a9ef","#004389"],["#ff6672","#a7000c"],["#66db72","#00750c"],["#b866db","#520075"],["#ffa966","#b64300"],["#ffff66","#c0a200"],["#6dffff","#07b1b1"],["#ff66ff","#b100a7"],["#f9ff66","#93b600"],["#ffe5e5","#bb7f7f"],["#66a7a7","#004141"],["#ffe5ff","#a77fc0"],["#d19566","#6b2f00"],["#ffffef","#c0bb89"],["#d1ffea","#6bc084"],["#a7a766","#414100"],["#ffffd8","#c09972"],["#a5ffff","#3fc1ff"],["#ffbef0","#ff588a"],["#e1fff0","#7bf38a"],["#ffc3ff","#d05df3"],["#ffffd6","#ffc170"],["#a5a5ff","#3f3fff"],["#ffffbe","#ffff58"],["#ebffff","#85ffff"],["#ffd7ff","#ff71ff"],["#a5ffff","#3fbfbf"],["#ffffcd","#e9ad67"],["#ffa5a5","#bf3f3f"],["#ffffa5","#bfbf3f"]]}};plateLayOutWidget=plateLayOutWidget||{};!function(e,u){plateLayOutWidget.createCanvasElements=function(){return{scaleFactor:1,baseSizes:{spacing:48,tile_radius:22,center_radius_complete:10,center_radius_incomplete:14,label_size:14,label_spacing:24,text_size:13,stroke:.5,gap:2},_setCanvasArea:function(e,t){this.scaleFactor=Math.min(t/(this.dimensions.rows*this.baseSizes.spacing+this.baseSizes.label_spacing),e/(this.dimensions.cols*this.baseSizes.spacing+this.baseSizes.label_spacing));var i={};for(var a in this.baseSizes)i[a]=this.baseSizes[a]*this.scaleFactor;this.sizes=i},_canvas:function(){this._fixRowAndColumn(),this._putCircles()},_fixRowAndColumn:function(){for(var e=this.dimensions.cols,t=this.dimensions.rows,i=this.sizes.spacing,a=this.sizes.label_spacing/2,n=this.sizes.label_spacing+this.sizes.spacing/2,l=this.sizes.label_size,s=a,r=n,o=1;o<=e;o++){var d=new u.IText(o.toString(),{fill:"black",originX:"center",originY:"center",fontSize:l,top:s,left:r,fontFamily:'"Roboto", Arial, sans-serif',selectable:!1,fontWeight:"400"});r+=i,this.mainFabricCanvas.add(d)}s=n,r=a;for(o=1;o<=t;o++){d=new u.IText(this.rowIndex[o-1],{fill:"black",originX:"center",originY:"center",fontSize:l,top:s,left:r,fontFamily:'"Roboto", Arial, sans-serif',selectable:!1,fontWeight:"400"});s+=i,this.mainFabricCanvas.add(d)}},_putCircles:function(){for(var e=this.dimensions.cols,t=this.dimensions.rows,i=0,a=0;a<t;a++)for(var n=0;n<e;n++){this.allTiles.length;var l=this._createTile(a,n);l.index=i++,this.allTiles.push(l),this.mainFabricCanvas.add(l.background),this.mainFabricCanvas.add(l.highlight),this.mainFabricCanvas.add(l.circle),this.mainFabricCanvas.add(l.circleCenter),this.mainFabricCanvas.add(l.circleText)}this._addLargeRectangleOverlay(),this._fabricEvents()},_createTile:function(e,t){var i={visible:!1,colorIndex:null};i.row=e,i.col=t,i.address=this.rowIndex[e]+(t+1);var a=(e+1)*this.sizes.spacing,n=(t+1)*this.sizes.spacing;return i.background=new u.Circle({top:a,left:n,radius:this.sizes.tile_radius,originX:"center",originY:"center",hasControls:!1,hasBorders:!1,lockMovementX:!0,lockMovementY:!0,evented:!1}),i.background.setGradient("fill",{type:"radial",x1:this.sizes.tile_radius,x2:this.sizes.tile_radius,y1:this.sizes.tile_radius+this.sizes.gap,y2:this.sizes.tile_radius+this.sizes.gap,r1:this.sizes.tile_radius-this.sizes.gap,r2:this.sizes.tile_radius,colorStops:{0:"rgba(0,0,0,0.1)",1:"rgba(0,0,0,0.2)"}}),i.highlight=new u.Rect({originX:"center",originY:"center",top:a,left:n,width:this.sizes.spacing,height:this.sizes.spacing,fill:"rgba(0,0,0,0.4)",evented:!1,visible:!1}),i.circle=new u.Circle({originX:"center",originY:"center",top:a,left:n,radius:this.sizes.tile_radius,stroke:"gray",strokeWidth:this.sizes.stroke,evented:!1,visible:!1}),i.circleCenter=new u.Circle({originX:"center",originY:"center",top:a,left:n,radius:this.sizes.center_radius_incomplete,fill:"white",stroke:"gray",strokeWidth:this.sizes.stroke,evented:!1,visible:!1}),i.circleText=new u.IText("",{originX:"center",originY:"center",top:a,left:n,fill:"black",fontFamily:'"Roboto", Arial, sans-serif',fontSize:this.sizes.text_size,lockScalingX:!0,lockScalingY:!0,evented:!1,visible:!1}),i},setTileComplete:function(e,t){e.circleText.fontWeight=t?(e.circleCenter.radius=this.sizes.center_radius_complete,e.circleText.fill="black","normal"):(e.circleCenter.radius=this.sizes.center_radius_incomplete,e.circleText.fill="red","bold")},setTileVisible:function(e,t){e.visible=t,e.circle.visible=e.visible,e.circleCenter.visible=e.visible,e.circleText.visible=e.visible},setTileColor:function(e,t,i){this.setTileVisible(e,!0),e.colorIndex=parseInt(t),e.circleText.text=String(e.colorIndex),0<t&&(t=(t-1)%(this.colorPairs.length-1)+1);var a=this.colorPairs[t];e.circle.setGradient("fill",{y2:2*this.sizes.tile_radius,colorStops:a})},_addLargeRectangleOverlay:function(){this.overLay=new u.Rect({width:632,height:482,left:0,top:0,opacity:0,originX:"left",originY:"top",lockMovementY:!0,lockMovementX:!0,selectable:!1}),this.mainFabricCanvas.add(this.overLay)}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(f,e){plateLayOutWidget.createField=function(){return{_createField:function(e){switch(e.data.type){case"text":this._createTextField(e);break;case"numeric":this._createNumericField(e);break;case"select":this._createSelectField(e);break;case"multiselect":this._createMultiSelectField(e);break;case"boolean":this._createBooleanField(e);break;case"multiplex":this._createMultiplexField(e)}},_createTextField:function(i){var e=i.id,t=this._createElement("<input>").attr("id",e).addClass("plate-setup-tab-input");i.root.find(".plate-setup-tab-field-container").append(t),this.defaultWell[e]=null,i.parseValue=function(e){return e=e?String(e):null},i.getValue=function(){var e=t.val().trim();return""==e&&(e=null),e},i.setValue=function(e){t.val(e)},i.getText=function(e){return null==e?"":e},i.disabled=function(e){i.input.prop("disabled",e)},i.parseText=i.parseValue,t.on("input",function(e,t){i.onChange()}),i.input=t},_createOpts:function(e){var t={allowClear:!0,placeholder:"select",minimumResultsForSearch:10};if(e.options)t.data=e.options;else{if(!e.query)throw"Must specify data or query";var i=e.query;e.delay&&(i=this._debounce(e.delay,i)),t.query=i}return t},_createSelectField:function(i){var a=i.id,t=this._createElement("<input/>").attr("id",a).addClass("plate-setup-tab-select-field");i.root.find(".plate-setup-tab-field-container").append(t),this.defaultWell[a]=null;var n=this._createOpts(i.data),l={};n.data.forEach(function(e){l[e.id]=e}),t.select2(n),i.parseValue=function(e){var t=e;if(""==t&&(t=null),null==t)return null;if(t in l)return l[t].id;throw"Invalid value "+e+" for select field "+a},i.disabled=function(e){i.input.prop("disabled",e)},i.getValue=function(){var e=t.select2("data");return e?e.id:null},i.setValue=function(e){e&&(e=l[e]),t.select2("data",e)},i.setOpts=function(e){t.select2("data",{}),n.data=e||[],t.select2(n)},i.getText=function(e){return null==e?"":l[e].text},i.parseText=function(e){var t=e;if(""==t&&(t=null),null==t)return null;if(t in l)return l[t].text;throw"Invalid text value "+e+" for select field "+a},t.on("change",function(e,t){i.onChange()}),i.input=t},_createMultiSelectField:function(l){var i=l.id,a=this,s=this._createElement("<input/>").attr("id",i).addClass("plate-setup-tab-multiselect-field");s.attr("multiple","multiple"),l.root.find(".plate-setup-tab-field-container").append(s),a.defaultWell[i]=null;var r=a._createOpts(l.data);r.multiple=!0;var n={};r.data.forEach(function(e){n[e.id]=e}),s.select2(r),l.disabled=function(e){l.input.prop("disabled",e)},l.parseValue=function(e){var t=e;return t=t&&t.length?t.map(function(e){if(e in n)return n[e].id;throw"Invalid value "+e+" for multiselect field "+i}):null},l.setOpts=function(e){var t=l.data.options,i=[];for(var a in t){var n=t[a];0<=e.indexOf(n.id)&&i.push(n)}r.data=i,s.select2(r)},l.getValue=function(){var e=s.select2("data");return e.length?e.map(function(e){return e.id}):null},l.setValue=function(e){e=(e=e||[]).map(function(e){return n[e]}),s.select2("data",e)},l.getText=function(e){return null==e?"":0<e.length?e.map(function(e){return n[e].text}).join("; "):""},l.multiOnChange=function(e,t){e&&(e=e.id.toString()),t&&(t=t.id.toString());var i={};i[l.id]={multi:!0,added:e,removed:t},a._addAllData(i)},l.parseText=function(e){var t=e;return t=t&&t.length?t.map(function(e){if(e in n)return n[e].text;throw"Invalid text value "+e+" for multiselect field "+i}):null},s.on("change",function(e,t){var i=e.added,a=e.removed;l.multiOnChange(i,a)}),l.input=s,a._createDeleteButton(l)},_createNumericField:function(n){var i=n.id,e=n.data,t=this._createElement("<input>").addClass("plate-setup-tab-input").attr("placeholder",e.placeholder||"").attr("id",i);n.root.find(".plate-setup-tab-field-container").append(t),this.defaultWell[i]=null;var a=e.units||[],l=e.defaultUnit||null,s=null;if(l?a.length?a.indexOf(l)<0&&(l=a[0]):a=[l]:a.length&&(l=a[0]),a.length)if(n.units=a,n.hasUnits=!0,n.defaultUnit=l,1==a.length){var r=f("<div></div>").addClass("plate-setup-tab-unit");r.text(l),n.root.find(".plate-setup-tab-field-container").append(r)}else{s=this._createElement("<input/>").attr("id",i).addClass("plate-setup-tab-label-select-field"),n.root.find(".plate-setup-tab-field-container").append(s);var o=null,d={data:a.map(function(e){var t={id:e,text:e};return e==l&&(o=t),t}),allowClear:!1,minimumResultsForSearch:10};s.select2(d),s.select2("data",o)}n.disabled=function(e){n.input.prop("disabled",e),s&&s.prop("disabled",e)},n.setUnitOpts=function(e){n.units=e||null;var t=[],i=n.defaultUnit=null;n.units&&n.units.length&&(n.defaultUnit=n.units[0],t=n.units.map(function(e){var t={id:e,text:e};return e==n.defaultUnit&&(i=t),t}));var a={data:t,allowClear:!1,minimumResultsForSearch:10};s.select2(a),s.select2("data",i)},n.parseValue=function(e){var t;if(f.isPlainObject(e)){if(n.hasUnits)return null===(t=n.parseRegularValue(e.value))?null:{value:t,unit:n.parseUnit(e.unit)};throw"Value must be plain numeric for numeric field "+i}return n.hasUnits?null===(t=n.parseRegularValue(e))?null:{value:t,unit:n.defaultUnit}:n.parseRegularValue(e)},n.getValue=function(){var e=n.getRegularValue();if(null===e||isNaN(e))return null;if(n.hasUnits){var t={value:e,unit:n.getUnit()};if(n.data.hasMultiplexUnit)for(var i in n.data.unitMap){n.data.unitMap[i].forEach(function(e){e.text===t.unit&&(t.unitTypeId=i,t.unitId=e.id)})}return t}return e},n.setValue=function(e){n.hasUnits?f.isPlainObject(e)?(n.setUnit(e.unit||n.defaultUnit),n.setRegularValue(e.value)):(n.setRegularValue(e),n.setUnit(n.defaultUnit)):n.setRegularValue(e)},n.parseRegularValue=function(e){if(null==e)return null;var t=String(e).trim();if(""===t)return null;if(t=Number(e),isNaN(t))throw"Invalid value "+e+" for numeric field "+i;return t},n.getRegularValue=function(){var e=t.val().trim();return e=""==e?null:Number(e)},n.setRegularValue=function(e){t.val(e)},n.parseUnit=function(e){if(null==e||""===e)return n.defaultUnit;for(var t=0;t<a.length;t++)if(e.toLowerCase()==a[t].toLowerCase())return a[t];throw"Invalid unit "+e+" for field "+i},n.getUnit=function(){return s?s.val():n.defaultUnit},n.setUnit=function(e){s&&(null!=(e=e||n.defaultUnit)&&(e={id:e,text:e}),s.select2("data",e))},n.getText=function(e){if("object"==typeof e&&e){var t=e.value,i=e.unit;return null==t?"":(t=t.toString(),i||(i=l),i&&(t=t+" "+i),t)}return n.getRegularText(e)},n.getRegularText=function(e){return null==e?"":e=e.toString()},n.parseText=function(e){var t=n.parseValue(e);return t&&"object"==typeof t?t.value+t.unit:t||null},t.on("input",function(){var e=n.getRegularValue();isNaN(e)?t.addClass("invalid"):t.removeClass("invalid"),n.onChange()}),s&&s.on("change",function(){n.onChange()}),n.input=t,n.unitInput=s},_createBooleanField:function(t){var i=t.id,a=this._createElement("<input/>").attr("id",i).addClass("plate-setup-tab-select-field");this.defaultWell[i]=null,t.root.find(".plate-setup-tab-field-container").append(a);var n={id:"true",text:"true"},l={id:"false",text:"false"},e={data:[n,l],placeholder:"select",allowClear:!0,minimumResultsForSearch:-1,initSelection:function(e,t){var i=e.val();t({id:i,text:i})}};a.select2(e),t.disabled=function(e){t.input.prop("disabled",e)},t.parseValue=function(e){if(null==e)return null;var t=String(e).trim().toLowerCase();if("true"==t)t=!0;else if("false"==t)t=!1;else{if(""!=t)throw"Invalid value "+e+" for boolean field "+i;t=null}return t},t.getValue=function(){switch(a.val()){case"true":return!0;case"false":return!1;default:return null}},t.setValue=function(e){e=1==e||"true"==e?n:0==e||"false"==e?l:null,a.select2("data",e)},t.getText=function(e){return null==e?"":e.toString()},t.parseText=t.parseValue,a.on("change",function(e){t.onChange()}),t.input=a},_createMultiplexField:function(o){var d=this;this._createMultiSelectField(o),d.defaultWell[o.id]=[];var e=d._createElement("<div></div>").addClass("plate-setup-tab-name-singleSelect").text("Select to edit"),t=d._createElement("<div></div>").addClass("plate-setup-tab-field-container-singleSelect");o.root.find(".plate-setup-tab-field-right-side").append(e,t),o.singleSelect=this._createElement("<input/>").attr("id",o.id+"SingleSelect").addClass("plate-setup-tab-multiplex-single-select-field"),o.singleSelect.appendTo(t),o.singleSelectValue=function(){var e=o.singleSelect.select2("data");return null!=e&&(e=e.id),e};var u=function(e,t){var i={allowClear:!1,placeholder:"select",minimumResultsForSearch:10,data:e||[]};t||(t=i.data.length?i.data[0]:null),o.singleSelect.select2("data",[]),o.singleSelect.select2(i),o.singleSelect.select2("data",t),o.singleSelect.prop("disabled",0==i.data.length)},c=function(){var t=o.singleSelectValue();o.updateSubFieldUnitOpts(t);var e=o.detailData||[],i=null;e.forEach(function(e){e[o.id]===t&&(i=e)}),i?o.subFieldList.forEach(function(e){e.disabled(!1),e.setValue(i[e.id])}):o.subFieldList.forEach(function(e){e.disabled(!0),e.setValue(null)}),d.readOnlyHandler()};u([]),o.singleSelect.on("change",c),o._changeMultiFieldValue=function(e,t){var i,a={};for(var n in o.data.multiplexFields){a[o.data.multiplexFields[n].id]=null}e&&(i=e.value?e.value:(a[o.id]=e.id,a),e={id:e.id,value:i}),t&&(i=t.value?t.value:(a[o.id]=t.id,a),t={id:t.id,value:i});var l={};l[o.id]={multi:!0,added:e,removed:t},d._addAllData(l)};var a=o.setValue;o.setValue=function(e){var t=null;(o.detailData=e)&&e.length&&(t=e.map(function(e){return e[o.id]})),a(t);var i=o.input.select2("data")||[];u(i),c()},o.disabled=function(t){o.input.prop("disabled",t),o.subFieldList.forEach(function(e){e.disabled(t)}),t?e.text("Select to inspect"):e.text("Select to edit")},o.parseValue=function(e){var t=e;return t=t&&t.length?t.map(function(t){var i={};for(var a in i[o.id]=t[o.id],t)o.subFieldList.forEach(function(e){e.id===a&&(i[e.id]=e.parseValue(t[a]))});return i}):null},o.updateSubFieldUnitOpts=function(t){var i;o.data.options.forEach(function(e){e.id===t&&(i=e)}),o.subFieldList.forEach(function(e){e.data.hasMultiplexUnit&&(i&&i.hasOwnProperty("unitOptions")?e.setUnitOpts(i.unitOptions[e.id]):e.setUnitOpts(null))})},o.multiOnChange=function(e,t){o._changeMultiFieldValue(e,t);var i=o.getValue(),l=o.detailData,s=[],a=null;l&&(s=l.map(function(e){return e[o.id]}));var r=[],n=[];i&&(i.forEach(function(a){if(l&&l.forEach(function(e){e[o.id]===a&&r.push(e)}),s.indexOf(a)<0){var n={};n[o.id]=a,o.updateSubFieldUnitOpts(a),o.subFieldList.forEach(function(i){if(i.hasUnits)if(i.data.hasMultiplexUnit)i.disabled(!1),o.data.options.forEach(function(e){if(e.id===a){var t={value:null,unit:i.units[0]};n[i.id]=i.parseValue(t)}});else{i.data.units&&1<i.data.units.length&&i.disabled(!1);var e={value:null,unit:i.defaultUnit};n[i.id]=i.parseValue(e)}else n[i.id]=i.parseValue(null)}),r.push(n)}}),i.forEach(function(t){o.data.options.forEach(function(e){e.id===t&&n.push(e)})}),a=n[i.length-1]),o.detailData=r,u(n,a),c()},o.getText=function(e){if(null===e)return"";if(o.id in d.globalSelectedMultiplexSubfield){var i=d.globalSelectedMultiplexSubfield[o.id],t=[];for(var a in e){var n=e[a],l=[];for(var s in o.data.options){var r=o.data.options[s];r.id===n[o.id]&&l.push(r.text)}o.subFieldList.forEach(function(e){if(0<=i.indexOf(e.id)){var t=e.getText(n[e.id]);l.push(e.name+": "+t)}}),t.push("{"+l.join(", ")+"}")}return t.join(";")}},o.parseText=function(e){if(null===e)return"";var t=[];for(var i in e){var a=e[i],n=[];for(var l in o.data.options){var s=o.data.options[l];s.id===a[o.id]&&n.push(s.text)}o.subFieldList.forEach(function(e){var t=e.getText(a[e.id]);t&&n.push(t)}),t.push(n)}return t},o.checkMultiplexCompletion=function(e){var t=0,i=0,s=!1;function a(e){var t=0,i=0;for(var a in o.subFieldList){var n=o.subFieldList[a],l=e[n.id];n.required&&(s=!0,t++,"object"==typeof l&&l?l.value&&i++:l&&i++)}return i/t}if(e)if(0<e.length)for(var n in e){t++,i+=a(e[n])}else o.required&&(s=!0,t=1);else o.required&&(s=!0,t=1);return{include:s,completionPct:i/t}},o.applyMultiplexSubFieldColor=function(e){var l={};o.subFieldList.forEach(function(e){e.required&&(l[e.id]={field:e,warningStatus:[]})}),e.forEach(function(e){!function(e){for(var t in o.subFieldList){var i=o.subFieldList[t];if(null===e)o.required&&i.required&&l[i.id].warningStatus.push(!0);else if("object"==typeof e)if(0===e.length)o.required&&i.required&&l[i.id].warningStatus.push(!0);else for(var a in e){var n=e[a][i.id];i.required&&("object"==typeof n&&n?n.value?l[i.id].warningStatus.push(!1):l[i.id].warningStatus.push(!0):n?l[i.id].warningStatus.push(!1):l[i.id].warningStatus.push(!0))}}}(e)});var t=[];for(var i in l){var a=l[i].field;if(0<=l[i].warningStatus.indexOf(!0)){var n=a.name+" is a required subfield for "+o.name+", please make sure all "+o.name+" have "+a.name;o.required,d.fieldWarningMsg(a,n,!0),t.push(!0)}else d.fieldWarningMsg(a,"none",!1),t.push(!1)}var s,r=!1;r=!(t.indexOf(!0)<0),s=o.required?o.name+" is a required field, please also fix missing required subfield(s) below":o.name+" is not a required field, please fix missing required subfield(s) below or remove selected "+o.name,d.fieldWarningMsg(o,s,r)},o.parseMainFieldVal=function(e){for(var t=o.data.options,i=0;i<t.length;i++){var a=t[i];if(a.id===e)return a.text}}},_deleteDialog:function(t){var e,i=this,a=t.allSelectedMultipleVal;e=a?Object.keys(a):[];var n=f("<div/>").addClass("delete-dialog modal");function l(){n.hide(),n.remove()}f("body").append(n);var s=f("<div/>").addClass("modal-content").appendTo(n),r=f("<div/>").appendTo(s),o=f("<div/>").addClass("dialog-buttons").css("justify-content","flex-end").appendTo(s);if(0<e.length){f("<p/>").text(t.name+" in selected wells: choose items to delete and click the delete button below").appendTo(r);var d=i._deleteDialogTable(t,a);if(d.appendTo(r),d.addClass("plate-popout-table"),d.find("td").addClass("plate-popout-td"),d.find("th").addClass("plate-popout-th"),d.find("tr").addClass("plate-popout-tr"),!i.readOnly){var u=f("<button class='multiple-field-manage-delete-button'>Delete Checked Items</button>");o.append(u),u.click(function(){d.find("input:checked").each(function(){var e=this.value;t.multiOnChange(null,{id:e})}),i.decideSelectedFields(),l()})}}else f("<p/>").text("No "+t.name+" in the selected wells").appendTo(r);var c=f("<button>Cancel</button>");o.append(c),c.click(l),n.show(),window.onclick=function(e){e.target==n[0]&&l()}},_deleteDialogTable:function(e,a){var n=this,t=[e.name,"Counts"];n.readOnly||t.push("Delete");var i=f("<table/>"),l=f("<thead/>").appendTo(i);f("<tr/>").appendTo(l).append(t.map(function(e){return f("<th/>").text(e)}));var s=f("<tbody/>").appendTo(i);return e.data.options.forEach(function(e){if(e.id in a){var t=f("<tr/>").appendTo(s),i=f("<input type='checkbox'>").prop("value",e.id);f("<td/>").text(e.text).appendTo(t),f("<td/>").text(a[e.id]).appendTo(t),n.readOnly||f("<td/>").append(i).appendTo(t)}}),i},_createDeleteButton:function(e){var t=this,i=f("<button/>").addClass("plate-setup-remove-all-button");i.id=e.id+"Delete",i.text("Manage "+e.name+"...");var a=t._createElement("<div></div>").addClass("plate-setup-remove-all-button-container");a.append(i),e.deleteButton=i,e.root.find(".plate-setup-tab-field-right-side").append(a),i.click(function(){t._deleteDialog(e)})}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(b,e){plateLayOutWidget.engine=function(v){return{engine:{derivative:{},stackUpWithColor:{},stackPointer:2,wellEmpty:function(e){for(var t in e){var i=e[t];if(null!=i){if(!Array.isArray(i))return!1;if(0<i.length)return!1}}return!0},searchAndStack:function(){this.stackUpWithColor={},this.stackPointer=1;var e={};for(var t in this.derivative){for(var i=this.derivative[t],a={},n=0;n<v.globalSelectedAttributes.length;n++){var l=v.globalSelectedAttributes[n];if(l in v.globalSelectedMultiplexSubfield){var s=v.globalSelectedMultiplexSubfield[l],r=[];for(var o in i[l]){var d=i[l][o],u={};u[l]=d[l],s.forEach(function(e){u[e]=d[e]}),r.push(u)}a[l]=r}else null!=i[l]&&(a[l]=i[l])}b.isEmptyObject(a)?e[t]=null:e[t]=JSON.stringify(a)}for(;!b.isEmptyObject(e);){var c=Object.keys(e).map(function(e){return parseFloat(e,10)});c.sort(function(e,t){return e-t});var f=c[0],h=e[f],p=[];if(h){for(n=0;n<c.length;n++){h==e[t=c[n]]&&(p.push(t),this.stackUpWithColor[this.stackPointer]=p,delete e[t])}0<p.length&&this.stackPointer++}else this.stackUpWithColor[0]?this.stackUpWithColor[0].push(f):this.stackUpWithColor[0]=[f],delete e[f]}},applyColors:function(){var e=0,t=0;v.addBottomTableHeadings();for(var i=0;i<v.allTiles.length;i++){var a=v.allTiles[i];v.setTileVisible(a,!1)}for(var n=0;n<this.stackPointer;n++){var l=this.stackUpWithColor[n];if(l)for(var s in v.addBottomTableRow(n,l),l){e++;var r=this.stackUpWithColor[n][s],o=(a=v.allTiles[r],this.derivative[r]);v.setTileColor(a,n,this.stackPointer);var d=this.checkCompletion(o,a);v.setTileComplete(a,1==d),t+=d}}t=Math.floor(100*t/e),isNaN(t)?v.overLayTextContainer.text("Completion Percentage: 0%"):v.overLayTextContainer.text("Completion Percentage: "+t+"%")},checkCompletion:function(e,t){for(var i=0,a=0,n=0;n<v.fieldList.length;n++){var l=v.fieldList[n];if(l.checkMultiplexCompletion){var s=l.checkMultiplexCompletion(e[l.id]);s.include&&(a+=s.completionPct,i++)}else l.required&&(i++,null!==e[l.id]&&a++)}return i===a?1:a/i}}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(u,n){plateLayOutWidget.fabricEvents=function(){return{colorToIndex:{},startCoords:{x:0,y:0},focalWell:{row:0,col:0},selectedAreas:[],_clickCoords:function(e){var t=e.e.target.getBoundingClientRect();return{x:e.e.clientX-t.left,y:e.e.clientY-t.top}},_fabricEvents:function(){var s=this;u(s.target).on("getPlates",function(e,t){s.getPlates(JSON.parse(t))}),s.mainFabricCanvas.on("mouse:down",function(e){s.selecting=!0;var t=s._clickCoords(e),i=s.selectedAreas.slice(),a=s.focalWell,n=s._wellToCoords(a,!0),l=s._coordsToRect(n,t);e.e.ctrlKey?(n=t,l=s._coordsToRect(n,t),a=s._coordsToWell(n),e.e.shiftKey?i=[s._rectToArea(l)]:i.push(s._rectToArea(l))):e.e.shiftKey?i[i.length-1]=s._rectToArea(l):(n=t,l=s._coordsToRect(n,t),a=s._coordsToWell(n),i=[s._rectToArea(l)]),s.startCoords=n,s.setSelection(i,a),s.mainFabricCanvas.renderAll()}),s.mainFabricCanvas.on("mouse:move",function(e){if(s.selecting){var t=s.selectedAreas.slice(),i=s._clickCoords(e),a=s._coordsToRect(s.startCoords,i),n=s._rectToArea(a);n&&(t[t.length-1]=n),s.setSelection(t,s.focalWell),s.mainFabricCanvas.renderAll()}}),s.mainFabricCanvas.on("mouse:up",function(e){s.selecting=!1;var t=s.selectedAreas.slice(),i=s._clickCoords(e),a=s._coordsToRect(s.startCoords,i),n=s._rectToArea(a);n&&(t[t.length-1]=n),s.setSelection(t,s.focalWell),s.decideSelectedFields(),s.mainFabricCanvas.renderAll(),s._trigger("selectedWells",null,{selectedAddress:s.getSelectedAddress()})})},setSelection:function(e,t){this.selectedAreas=e,this.focalWell=t,this.allSelectedObjects=this._areasToTiles(e),this._setSelectedTiles(),this._setFocalWellRect(this.focalWell),document.activeElement.blur()},_setFocalWellRect:function(e){var t;if(this.disableAddDeleteWell){var i=this.locToAddress({r:e.row,c:e.col});this.addressAllowToEdit.indexOf(i)<0?(t=!1,this.setFieldsDisabled(!0)):(t=!0,this.setFieldsDisabled(!1))}else e&&(t=!0);if(t){var a=this._areaToRect(this._wellToArea(e));this.focalWellRect?(this.focalWellRect.top=a.top,this.focalWellRect.left=a.left,this.focalWellRect.width=a.width-2,this.focalWellRect.height=a.height-2):(this.focalWellRect=new n.Rect({width:a.width-2,height:a.height-2,left:a.left,top:a.top,fill:null,strokeWidth:2,stroke:"black",selectable:!1}),this.mainFabricCanvas.add(this.focalWellRect))}else this.mainFabricCanvas.remove(this.focalWellRect),this.focalWellRect=null},_setSelectedTiles:function(){var i=this.allSelectedObjects;this.allTiles.forEach(function(e){var t=0<=i.indexOf(e);e.highlight.visible=t})},_getSelectedWells:function(){var i=this;return this.allSelectedObjects.map(function(e){var t=i.engine.derivative[e.index];return t||(t=i.defaultWell),t})},_getCommonFields:function(e){if(e.length){for(var t=e[0],i=u.extend(!0,{},t),a=1;a<e.length;a++){var n=e[a];for(var l in i)if(Array.isArray(i[l])){for(var s=i[l],r=[],o=0;o<s.length;o++){var d=s[o];d&&"object"==typeof d?this.containsObject(d,n[l])&&r.push(d):0<=u.inArray(d,n[l])&&r.push(d)}i[l]=r}else n[l]&&"object"==typeof n[l]&&i[l]&&"object"==typeof i[l]?n[l].value===i[l].value&&n[l].unit===i[l].unit||delete i[l]:i[l]!=n[l]&&delete i[l]}return i}return{}},containsObject:function(n,e){var t=[];return!!e&&(e.forEach(function(i){var a=[];Object.keys(i).forEach(function(e){if(0<=Object.keys(n).indexOf(e)){var t=i[e];"object"==typeof t&&t?n[e]?a.push(t.unit===n[e].unit&&t.value===n[e].value):a.push(!1):a.push(t===n[e])}}),t.push(a.indexOf(!1)<0)}),0<=t.indexOf(!0))},_getCommonWell:function(e){if(e.length){for(var t=e[0],i=u.extend(!0,{},t),a=1;a<e.length;a++){var n=e[a];for(var l in i)if(Array.isArray(i[l])){for(var s=i[l],r=[],o=0;o<s.length;o++){var d=s[o];"object"==typeof s[o]?this.containsObject(d,n[l])&&r.push(d):0<=u.inArray(d,n[l])&&r.push(d)}i[l]=r}else n[l]&&"object"==typeof n[l]&&i[l]&&"object"==typeof i[l]?n[l].value===i[l].value&&n[l].unit===i[l].unit||(i[l]=null):i[l]!=n[l]&&(i[l]=null)}return i}return this.defaultWell},_getAllMultipleVal:function(e){this.multipleFieldList.forEach(function(i){if(e.length){var a={};e.forEach(function(e){var t=i.id;e[t]&&0<e[t].length&&e[t].forEach(function(e){"object"==typeof e?e[t]in a?a[e[t]]++:a[e[t]]=1:e in a?a[e]++:a[e]=1})}),i.allSelectedMultipleVal=a}else i.allSelectedMultipleVal=null})},decideSelectedFields:function(){var e=this._getSelectedWells();this._getAllMultipleVal(e),this.applyFieldWarning(e);var t=this._getCommonWell(e);this._addDataToTabFields(t)},getDifferentWellsVals:function(e){var t=[];for(var i in e)t.push(e[i]);var a={};if(1<t.length){var n=this._getCommonWell(t),l={};for(var s in e[0])l[s]=[];for(var r in t){var o={},d=t[r];for(var u in d){var c=n[u],f=d[u],h=null;if(Array.isArray(f)){h=[];for(var p=0;p<f.length;p++){var v=f[p];v?this.containsObject(v,c)||(h.push(v),this.containsObject(v,l[u])||l[u].push(v)):0<=c.indexOf(v)&&(h.push(v),0<=!l[u].indexOf(v)&&l[u].push(v))}}else f&&"object"==typeof f?c&&"object"==typeof c?f.value!==c.value&&f.unit!==c.unit&&(h=f,this.containsObject(f,l[u])||l[u].push(f)):(h=f,this.containsObject(f,l[u])||l[u].push(f)):f!==c&&(h=f,0<=!l[u].indexOf(f)&&l[u].push(f));o[u]=h}a[r]=o}for(var u in l)if(0===l[u].length)for(var r in a)delete a[r][u];return a}if(e[0]){var b={};for(var u in e[0]){f=e[0][u];Array.isArray(f)?0<f.length&&(b[u]=f):f&&(b[u]=f)}return{0:b}}},getWellSetAddressWithData:function(){var e=[],t=this.engine.derivative;for(var i in t)e.push(this.indexToAddress(i));return e}}}}(jQuery,fabric),(plateLayOutWidget=plateLayOutWidget||{}).assets=function(){return{_assets:{doImg:"✓",dontImg:"",warningImg:"⚠"}}};plateLayOutWidget=plateLayOutWidget||{};!function(i,e){plateLayOutWidget.interface=function(){return{_createInterface:function(){var e="<div></div>";this.container=this._createElement(e).addClass("plate-setup-wrapper"),this.topSection=this._createElement(e).addClass("plate-setup-top-section"),this.topLeft=this._createElement(e).addClass("plate-setup-top-left"),this.topRight=this._createElement(e).addClass("plate-setup-top-right"),this.overLayContainer=this._createElement(e).addClass("plate-setup-overlay-container"),this.canvasContainer=this._createElement(e).addClass("plate-setup-canvas-container"),this._createOverLay(),i(this.topLeft).append(this.overLayContainer),this._createCanvas(),i(this.topLeft).append(this.canvasContainer),i(this.topSection).append(this.topLeft),i(this.topSection).append(this.topRight),i(this.container).append(this.topSection),i(this.element).append(this.container),this._initiateFabricCanvas(),this._createTabAtRight(),this._createTabs(),this._placePresetTabs(),this._bottomScreen(),this._canvas(),this.bottomForFirstTime();var t=this;this._setShortcuts(),i(document.body).keyup(function(e){t._handleShortcuts(e)}),this._configureUndoRedoArray()},_createElement:function(e){return i(e)},_setShortcuts:function(){var t=this;window.addEventListener("cut",function(e){document.activeElement==document.body&&(t.copyCriteria(),t.clearCriteria(),e.preventDefault())}),window.addEventListener("copy",function(e){document.activeElement==document.body&&(t.copyCriteria(),e.preventDefault())}),window.addEventListener("paste",function(e){document.activeElement==document.body&&(t.pasteCriteria(),e.preventDefault())})},_handleShortcuts:function(e){document.activeElement===document.body&&(46==e.keyCode?(this.clearCriteria(),e.preventDefault()):(e.ctrlKey||e.metaKey)&&(90==e.keyCode?(e.shiftKey?this.redo():this.undo(),e.preventDefault()):89==e.keyCode&&(this.redo(),e.preventDefault())))}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(t,e){plateLayOutWidget.loadPlate=function(e){return{getPlates:function(e){var t={};for(var i in e.derivative){var a=e.derivative[i];t[i]=this.sanitizeWell(a)}var n=e.checkboxes||[],l=this.sanitizeAreas(e.selectedAreas,e.focalWell),s={derivative:t,checkboxes:n,selectedAreas:l.selectedAreas,focalWell:l.focalWell};this.setData(s)},sanitizeAreas:function(e,t){var i=this,a=this.dimensions.rows,n=this.dimensions.cols;if(e||(e=[]),e.length){var l=(e=e.map(function(e){return{minCol:i._coordIndex(Math.min(e.minCol,e.maxCol),n),minRow:i._coordIndex(Math.min(e.minRow,e.maxRow),a),maxCol:i._coordIndex(Math.max(e.minCol,e.maxCol),n),maxRow:i._coordIndex(Math.max(e.minRow,e.maxRow),a)}}))[e.length-1];t&&!this._wellInArea(t,l)&&(t=null),t||(t={row:l.minRow,col:l.minCol})}else t||(t={row:0,col:0}),e=[this._wellToArea(t)];return{selectedAreas:e,focalWell:t}},sanitizeWell:function(e){for(var t={},i=0;i<this.fieldList.length;i++){var a=this.fieldList[i];t[a.id]=a.parseValue(e[a.id])}return t},setData:function(e){this.engine.derivative=t.extend(!0,{},e.derivative),this.setCheckboxes(e.checkboxes),this.setSelection(e.selectedAreas,e.focalWell),this._colorMixer(),this.decideSelectedFields(),this.mainFabricCanvas.renderAll()}}}}(jQuery,fabric);var GET_PLATES="getPlates",IS_READ_ONLY="isReadOnly",IS_DISABLE_ADD_DELETE_WELL="isDisableAddDeleteWell",GET_SELECTED_OBJECT="getSelectedObject",SETSELECTEDWELL="setSelectedWell";plateLayOutWidget=plateLayOutWidget||{};jQuery,fabric,plateLayOutWidget.overlay=function(){return{_createOverLay:function(){var t=this;this.overLayTextContainer=this._createElement("<div></div>").addClass("plate-setup-overlay-text-container"),this.overLayTextContainer.text("Completion Percentage:"),this.overLayContainer.append(this.overLayTextContainer),this.overLayButtonContainer=this._createElement("<div></div>").addClass("plate-setup-overlay-button-container"),this.overLayContainer.append(this.overLayButtonContainer),this.clearCriteriaButton=this._createElement("<button />").addClass("plate-setup-button"),this.clearCriteriaButton.text("Clear"),this.overLayButtonContainer.append(this.clearCriteriaButton),this.clearCriteriaButton.click(function(e){t.clearCriteria()}),this.copyCriteriaButton=this._createElement("<button />").addClass("plate-setup-button"),this.copyCriteriaButton.text("Copy"),this.overLayButtonContainer.append(this.copyCriteriaButton),this.copyCriteriaButton.click(function(e){t.copyCriteria()}),this.pasteCriteriaButton=this._createElement("<button />").addClass("plate-setup-button"),this.pasteCriteriaButton.text("Paste"),this.overLayButtonContainer.append(this.pasteCriteriaButton),this.pasteCriteriaButton.click(function(e){t.pasteCriteria()}),this.undoButton=this._createElement("<button />").addClass("plate-setup-button"),this.undoButton.text("Undo"),this.overLayButtonContainer.append(this.undoButton),this.undoButton.click(function(e){t.undo()}),this.redoButton=this._createElement("<button />").addClass("plate-setup-button"),this.redoButton.text("Redo"),this.overLayButtonContainer.append(this.redoButton),this.redoButton.click(function(e){t.redo()})},clearCriteria:function(){if(this.allSelectedObjects){for(var e=this.allSelectedObjects.length,t=!1,i=0;i<e;i++){var a=this.allSelectedObjects[i];if(a.index in this.engine.derivative){if(this.emptyWellWithDefaultVal&&this.disableAddDeleteWell){var n=JSON.parse(JSON.stringify(this.defaultWell)),l=this.emptyWellWithDefaultVal;for(var s in l)s in n?(n[s]=l[s],this._applyFieldData(s,l[s])):console.log("Well does not contain key: "+s+", please contact support");this.engine.derivative[a.index]=n}else delete this.engine.derivative[a.index];t=!0}}t&&this.derivativeChange(),this._colorMixer(),this.decideSelectedFields()}else alert("Please select any well")},copyCriteria:function(){if(this.allSelectedObjects){var e=this._getSelectedWells();this.commonWell=this._getCommonFields(e)}else alert("Please select any well.")},pasteCriteria:function(){this.commonWell&&(this._addAllData(this.commonWell),this.decideSelectedFields(),this.mainFabricCanvas.renderAll())}}},$.widget("DNA.plateLayOut",{plateLayOutWidget:{},options:{value:0},allTiles:[],addressToLoc:function(e){var t=/^([A-Z]+)(\d+)$/.exec(e.trim().toUpperCase());if(t){for(var i,a=t[1],n=parseInt(t[2])-1,l=0;l<a.length;l++){var s=a.charCodeAt(l)-65;l?(i+=1,i*=26,i+=s):i=s}return{r:i,c:n}}throw e+" not a proper layout address"},locToIndex:function(e,i){if(i||(i=this.dimensions),e.r<0&&t,!(0<=e.r&&e.r<i.rows))throw"Row index "+(e.r+1)+" invalid";if(!(0<=e.c&&e.c<i.cols))throw"Column index "+(e.c+1)+" invalid";return e.r*i.cols+e.c},addressToIndex:function(e,t){var i=this.addressToLoc(e);return this.locToIndex(i,t)},_rowKey:function(e){var t=e%26,i=(e-t)/26,a=String.fromCharCode(65+t);return 0<i&&(a=String.fromCharCode(64+i)+a),a},indexToLoc:function(e,t){if(t||(t=this.dimensions),e>=t.rows*t.cols)throw"Index too high: "+e.toString(10);var i={};return i.c=e%t.cols,i.r=(e-i.c)/t.cols,i},locToAddress:function(e){return this._rowKey(e.r)+(e.c+1).toString(10)},indexToAddress:function(e,t){var i=this.indexToLoc(e,t);return this.locToAddress(i)},getDimensions:function(){return $.extend(!0,{},this.dimensions)},_create:function(){var e=parseInt(this.options.numRows||8),t=parseInt(this.options.numCols||12);this.dimensions={rows:e,cols:t},this.rowIndex=[];for(var i=0;i<e;i++)this.rowIndex.push(this._rowKey(i));for(var a in this.target=this.element[0].id?"#"+this.element[0].id:"."+this.element[0].className,this.options.readOnly&&this.isReadOnly(!0),plateLayOutWidget)$.extend(this,new plateLayOutWidget[a](this));return this.imgSrc=this.options.imgSrc||"assets",this._createInterface(),this._trigger("created",null,this),this},_init:function(){},addData:function(){alert("wow this is good")},getTextDerivative:function(e){var t={};this.fieldMap;for(var i in e){var a={},n={},l=e[i];for(var s in l)if(s in this.fieldMap){var r=this.fieldMap[s],o=r.parseText(l[s]);n[r.name]=o,a[s]=o}else n[s]=l[s],a[s]=l[s];t[i]={textVal:a,textFieldVal:n}}return t},getWellsDifferences:function(e){return this.getDifferentWellsVals(e)},setFieldsDisabled:function(t){this.fieldList.forEach(function(e){e.disabled(t)})},isReadOnly:function(e){this.readOnly=!!e,this.readOnlyHandler()},readOnlyHandler:function(){this.readOnly?(this.overLayButtonContainer.css("display","none"),$(".multiple-field-manage-delete-button").css("display","none"),this.setFieldsDisabled(!0)):(this.overLayButtonContainer.css("display","flex"),$(".multiple-field-manage-delete-button").css("display","none"),this.disableAddDeleteWell||this.setFieldsDisabled(!1))},disableAddDeleteWell:null,isDisableAddDeleteWell:function(e,t){e?(this.disableAddDeleteWell=!0,this.addressAllowToEdit=this.getWellSetAddressWithData(),this.actionPointer=0,this.undoRedoArray=[],this.undoRedoArray.push(this.createObject()),t&&(this.emptyWellWithDefaultVal=t)):(this.disableAddDeleteWell=!1,this.setFieldsDisabled(!1),this.emptyWellWithDefaultVal=null),this._fabricEvents()},getSelectedObject:function(){for(var e=[],t=0;t<this.allSelectedObjects.length;t++)e.push(this.allSelectedObjects[t].address);var i={},a=this.engine.derivative;for(var n in a){var l=this.indexToAddress(n);0<=e.indexOf(l)&&(i[l]=a[n])}return i},getSelectedIndex:function(){return this.allSelectedObjects.map(function(e){return that.addressToIndex(e.address)})},getSelectedAddress:function(){return this.allSelectedObjects.map(function(e){return e.address})},setSelectedWell:function(e){for(var t=[],i=999,a={},n=0;n<e.length;n++){var l=this.addressToIndex(e[n]),s=this.indexToLoc(l);t.push({minCol:s.c,minRow:s.r,maxCol:s.c,maxRow:s.r}),s.r<=i&&(i=s.r,s.r in a?a[s.r].push(s.c):a[s.r]=[s.c])}var r={row:i,col:Math.min.apply(null,a[i])};this.setSelection(t,r),this.decideSelectedFields(),this.mainFabricCanvas.renderAll()}});plateLayOutWidget=plateLayOutWidget||{};!function(s,e){plateLayOutWidget.preset=function(e){return{presets:[],_placePresetTabs:function(){var e=this.options.attributes.presets;if(e&&e.length){this.wellAttrContainer=this._createElement("<div></div>").addClass("plate-setup-well-attr-container").text("Checkbox presets"),this.tabContainer.append(this.wellAttrContainer),this.presetTabContainer=this._createElement("<div></div>").addClass("plate-setup-preset-container"),this.tabContainer.append(this.presetTabContainer);for(var t=0;t<e.length;t++){var i=e[t],a=this._createElement("<div></div>").addClass("plate-setup-prest-tab-div").text(i.title),n=this._createElement("<div></div>").addClass("plate-setup-prest-tab").data("preset",i.fields).append(a);this.presetTabContainer.append(n);var l=this;n.click(function(){var e=s(this);l._selectPreset(e)}),this.presets.push(n)}}},_clearPresetSelection:function(){for(var e=0;e<this.presets.length;e++){this.presets[e].removeClass("plate-setup-prest-tab-selected").addClass("plate-setup-prest-tab")}},_selectPreset:function(e){this.setCheckboxes(e.data("preset")),e.removeClass("plate-setup-prest-tab").addClass("plate-setup-prest-tab-selected")}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(a,e){plateLayOutWidget.tabs=function(){return{allTabs:[],defaultWell:{},allDataTabs:[],_createTabAtRight:function(){this.tabContainer=this._createElement("<div></div>").addClass("plate-setup-tab-container"),a(this.topRight).append(this.tabContainer)},_createTabs:function(){this.tabHead=this._createElement("<div></div>").addClass("plate-setup-tab-head"),a(this.tabContainer).append(this.tabHead);var e=this.options.attributes.tabs,i=this;e.forEach(function(e,t){i.allTabs[t]=i._createElement("<div></div>").addClass("plate-setup-tab"),a(i.allTabs[t]).data("index",t).text(e.name),a(i.allTabs[t]).click(function(){i._tabClickHandler(this)}),a(i.tabHead).append(i.allTabs[t])}),this.tabDataContainer=this._createElement("<div></div>").addClass("plate-setup-tab-data-container"),a(this.tabContainer).append(this.tabDataContainer),this._addDataTabs(e),a(this.allTabs[0]).click(),this._addTabData()},_tabClickHandler:function(e){if(this.selectedTab){a(this.selectedTab).removeClass("plate-setup-tab-selected").addClass("plate-setup-tab");var t=a(this.selectedTab).data("index");a(this.allDataTabs[t]).css("z-index",0),this.readOnlyHandler()}a(e).addClass("plate-setup-tab-selected"),this.selectedTab=e;var i=a(e).data("index");a(this.allDataTabs[i]).css("z-index",1e3)},_addDataTabs:function(e){var t=0;for(var i in e)this.allDataTabs[t++]=this._createElement("<div></div>").addClass("plate-setup-data-div").css("z-index",0),a(this.tabDataContainer).append(this.allDataTabs[t-1])}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(i,e){plateLayOutWidget.undoRedoManager=function(e){return{undoRedoArray:[],actionPointer:null,addToUndoRedo:function(e){if(null!=this.actionPointer){var t=this.actionPointer+1;t<this.undoRedoArray.length&&this.undoRedoArray.splice(t,this.undoRedoArray.length-t)}this.actionPointer=null,this.undoRedoArray.push(i.extend(!0,{},e))},_configureUndoRedoArray:function(){this.undoRedoArray=[],this.actionPointer=null,this.undoRedoArray.push(i.extend({},{checkboxes:[],derivative:{},selectedAreas:[{minRow:0,minCol:0,maxRow:0,maxCol:0}],focalWell:{row:0,col:0}}))},undo:function(){return console.log("undo"),this.shiftUndoRedo(-1)},redo:function(){return console.log("redo"),this.shiftUndoRedo(1)},shiftUndoRedo:function(e){var t=this.actionPointer;return null==t&&(t=this.undoRedoArray.length-1),t+=e,this.setUndoRedo(t)},setUndoRedo:function(e){return!(e<0)&&(!(e>=this.undoRedoArray.length)&&(this.undoRedoActive=!0,this.setData(this.undoRedoArray[e]),this.actionPointer=e,this.undoRedoActive=!1,this.derivativeChange(),!0))}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};jQuery,fabric,plateLayOutWidget.wellArea=function(e){return{_areasToTiles:function(e){var l=this.dimensions.cols,s=this;return e.reduce(function(e,t){if(t)for(var i=t.minRow;i<=t.maxRow;i++)for(var a=t.minCol;a<=t.maxCol;a++){var n=s.allTiles[a+l*i];e.indexOf(n)<0&&(s.disableAddDeleteWell?0<=s.addressAllowToEdit.indexOf(n.address)&&e.push(n):e.push(n))}return e},[])},_encodeArea:function(e){return e.minRow==e.maxRow&&e.minCol==e.maxCol?this.rowIndex[e.minRow]+e.minCol.toString(10):this.rowIndex[e.minRow]+e.minCol.toString(10)+":"+this.rowIndex[e.maxRow]+e.maxCol.toString(10)},_encodeAreas:function(e){var t=this;return e.map(function(e){return t._encodeArea(e)}).join(",")},_decodeWell:function(e){var t,i=new RegExp("^\\s*("+this.rowIndex.join("|")+")(\\d+)\\s*$");if(t=e.match(i)){var a=this.rowIndex.indexOf(t[1]);if(0<=a)return{row:a,col:parseInt(t[2])-1}}if(t=e.match(/^\s*R(\d+)C(\d+)\s*$/i))return{row:parseInt(t[1])-1,col:parseInt(t[2])-1};throw"Invalid well address: "+e},_decodeArea:function(e){var t=this,i=e.split(":").map(function(e){return t._decodeWell(e)});if(1==i.length)return{minRow:i[0].row,minCol:i[0].col,maxRow:i[0].row,maxCol:i[0].col};if(2!=i.length)throw"Invalid address: "+e;return Math.min(i[0].row,i[1].row),{minRow:Math.min(i[0].row,i[1].row),minCol:Math.min(i[0].col,i[1].col),maxRow:Math.max(i[0].row,i[1].row),maxCol:Math.max(i[0].col,i[1].col)}},_decodeAreas:function(e){var t=this;return e.split(",").map(function(e){return t._decodeArea(e)})},_wellToArea:function(e){return{minCol:e.col,minRow:e.row,maxCol:e.col,maxRow:e.row}},_wellInArea:function(e,t){return e.row>=t.minRow&&e.row<=t.maxRow&&e.col>=t.minCol&&e.col<=t.maxCol},_coordsToRect:function(e,t){var i=Math.min(e.x,t.x);return{top:Math.min(e.y,t.y),left:i,height:Math.abs(t.y-e.y),width:Math.abs(t.x-e.x)}},_coordIndex:function(e,t){return e<0?0:t<=e?t-1:Math.floor(e)},_coordsToWell:function(e){var t=this.dimensions.cols,i=this.dimensions.rows,a=this.sizes.spacing,n=this.sizes.label_spacing,l=(e.x-n)/a,s=(e.y-n)/a;return{row:this._coordIndex(s,i),col:this._coordIndex(l,t)}},_wellToCoords:function(e,t){var i=this.sizes.spacing,a=this.sizes.label_spacing,n=e.col*i+a,l=e.row*i+a;if(t){var s=i/2;n+=s,l+=s}return{x:n,y:l}},_areaToRect:function(e){var t=e.maxRow-e.minRow+1,i=e.maxCol-e.minCol+1,a=this.sizes.spacing,n=this.sizes.label_spacing;return{top:e.minRow*a+n,left:e.minCol*a+n,height:t*a,width:i*a}},_rectToArea:function(e){var t=this.dimensions.rows,i=this.dimensions.cols,a=this.sizes.spacing,n=this.sizes.label_spacing,l=(e.left-n)/a,s=(e.top-n)/a,r=e.height/a,o=l+e.width/a,d=s+r;return o<0&&(o=i),i<=l&&(l=0),d<0&&(d=t),s<=0&&(s=0),{minCol:this._coordIndex(l,i),minRow:this._coordIndex(s,t),maxCol:this._coordIndex(o,i),maxRow:this._coordIndex(d,t)}}}}; -//# sourceMappingURL=plate-map.min.js.map \ No newline at end of file diff --git a/dist/js/plate-map.min.js.map b/dist/js/plate-map.min.js.map deleted file mode 100644 index da1b0dd..0000000 --- a/dist/js/plate-map.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["add-data-on-change.js","add-data-to-tabs.js","add-tab-data.js","add-warning-msg.js","bottom-table.js","canvas.js","check-box.js","color-manager.js","create-canvas-elements.js","create-field.js","engine.js","fabric-events.js","image_assets.js","interface.js","load-plate.js","main.js","overlay.js","plate-layout.js","preset.js","tabs.js","undo-redo-manager.js","well-area.js"],"names":["plateLayOutWidget","$","fabric","addDataOnChange","_addAllData","data","this","allSelectedObjects","noOfSelectedObjects","length","wells","objectIndex","well","tile","index","engine","derivative","extend","defaultWell","processedData","processWellData","wellEmpty","emptyWellWithDefaultVal","disableAddDeleteWell","wellCopy","JSON","parse","stringify","defaultValue","key","_applyFieldData","_getAllMultipleVal","applyFieldWarning","_colorMixer","derivativeChange","newData","curWell","wellList","id","v","undefined","multi","curData","preData","newDt","_getMultiData","push","fieldId","addNew","added","removed","value","add","listIdx","toString","map","val","subFieldId","indexOf","removeIndex","removeListIndex","newPreData","idx","parseInt","undoRedoActive","createObject","addToUndoRedo","searchAndStack","applyColors","mainFabricCanvas","renderAll","_trigger","checkboxes","globalSelectedAttributes","slice","selectedAreas","focalWell","requiredField","jQuery","addDataToFields","_addDataToTabFields","values","fieldMap","setValue","addTabData","fieldList","autoId","_addTabData","tabData","options","attributes","tabs","that","multiplexFieldArray","forEach","tab","tabPointer","tabFields","fieldArray","field","field_val","console","log","type","_makeMultiplexField","_makeRegularField","allDataTabs","multipleFieldList","_makeSubField","wrapperDiv","_createElement","addClass","wrapperDivLeftSide","wrapperDivRightSide","nameContainer","text","name","fieldContainer","append","root","required","checkbox","_addCheckBox","_createField","onChange","getValue","subFieldList","requiredSubField","subFieldKey","multiplexFields","subFieldData","subField","multiplexId","subFields","subfield","mainMultiplexField","mainRefField","curId","singleSelectValue","curVal","returnVal","_changeMultiFieldValue","curDataLs","detailData","input","select2","i","addWarningMsg","fieldWarningMsg","include","imgId","img","html","_assets","warningImg","attr","find","prepend","popText","hover","e","style","display","hide","remove","removeWarningMsg","fieldData","applyMultiplexSubFieldColor","Array","bottomTable","_bottomScreen","bottomContainer","bottomTableContainer","container","addBottomTableHeadings","bottomRow","singleField","empty","rowCounter","adjustFieldWidth","tileAttrText","getText","addBottomTableRow","color","singleStack","modelTile","allTiles","row","plateIdDiv","numberText","click","evt","addressToSelect","addressIdx","indexToAddress","ctrlKey","getSelectedAddress","setSelectedWell","selectedAddress","colorPairs","colorStops","css","dataDiv","bottomForFirstTime","createExportButton","downloadCSV","csv","filename","csvFile","downloadLink","Blob","document","createElement","download","href","window","URL","createObjectURL","body","appendChild","exportData","format","rows","querySelectorAll","colorLocMap","colorLocIdxMap","stackUpWithColor","dim","getDimensions","colorIdx","locIdx","cols","j","innerText","replace","loc","join","overlayContainer","descriptionDiv","buttonContainer","exportButton","resetExportText","classList","setTimeout","clipboardButton","clipboard","ClipboardJS","get","resetClipboardText","on","canvas","allPreviouslySelectedObjects","colorPointer","goldenRatio","_createCanvas","normalCanvas","canvasContainer","_initiateFabricCanvas","w","width","h","height","_setCanvasArea","Canvas","backgroundColor","selection","stateful","hoverCursor","renderOnAddRemove","setWidth","setHeight","checkBox","checkImage","dontImg","_applyCheckboxHandler","checkBoxImage","machineClick","changes","changeCheckboxes","changeSubFieldsCheckboxes","subFieldToInclude","clicked","Boolean","doImg","gsa","multiplexCheckedSubField","globalSelectedMultiplexSubfield","_clearPresetSelection","setSubFieldCheckboxes","fieldIds","setCheckboxes","colorManager","createCanvasElements","scaleFactor","baseSizes","spacing","tile_radius","center_radius_complete","center_radius_incomplete","label_size","label_spacing","text_size","stroke","gap","Math","min","dimensions","sizes","prop","_canvas","_fixRowAndColumn","_putCircles","d1","d2","fontSize","top","left","tempFabricText","IText","fill","originX","originY","fontFamily","selectable","fontWeight","rowIndex","tileCounter","col","_createTile","background","highlight","circle","circleCenter","circleText","_addLargeRectangleOverlay","_fabricEvents","visible","colorIndex","address","Circle","radius","hasControls","hasBorders","lockMovementX","lockMovementY","evented","setGradient","x1","x2","y1","y2","r1","r2","0","1","Rect","strokeWidth","lockScalingX","lockScalingY","setTileComplete","complete","setTileVisible","setTileColor","stackPointer","String","overLay","opacity","createField","_createTextField","_createNumericField","_createSelectField","_createMultiSelectField","_createBooleanField","_createMultiplexField","parseValue","trim","disabled","bool","parseText","generated","_createOpts","config","opts","allowClear","placeholder","minimumResultsForSearch","query","delay","_debounce","optMap","opt","setOpts","multiple","allOpts","selectedVal","curOpts","multiOnChange","_createDeleteButton","units","defaultUnit","unitInput","hasUnits","unitText","selected","unit","o","setUnitOpts","newUnits","curUnit","cleanUnit","newOpts","isPlainObject","parseRegularValue","parseUnit","getRegularValue","isNaN","getUnit","hasMultiplexUnit","unitTypeKey","unitMap","setUnit","setRegularValue","Number","toLowerCase","u","getRegularText","textVal","removeClass","tval","fval","initSelection","element","callback","nameContainer1","fieldContainer1","singleSelect","appendTo","setSingleSelectOptions","selected_v","singleSelectChange","updateSubFieldUnitOpts","curSubField","readOnlyHandler","newSubFieldValue","subFieldName","multiselectSetValue","multiselectValues","newOptions","valMap","hasOwnProperty","unitOptions","curIds","curOpt","newMultiplexVal","selectList","newVal","selectId","checkedSubfields","valIdx","subV","subText","optId","x","checkMultiplexCompletion","valList","valCount","completionPct","getSubfieldStatus","vals","req","subFieldWarningMap","warningStatus","multiplexVals","multiplexIdx","updateSubFieldWarningMap","mainFieldStatus","warningText","mainFieldWarning","parseMainFieldVal","_deleteDialog","valToRemove","allSelectedMultipleVal","Object","keys","dialogDiv","killDialog","dialogContent","tableArea","buttonRow","table","_deleteDialogTable","readOnly","deleteCheckedButton","each","decideSelectedFields","cancelButton","show","onclick","event","target","colName","thead","tbody","tr","deleteButton","THIS","isArray","derivativeJson","wellData","selectedSubFields","curMultiplexVals","isEmptyObject","k","parseFloat","sort","a","b","refDerivativeIndex","referenceDerivative","arr","wholeNoTiles","wholePercentage","tileIndex","completion","checkCompletion","floor","overLayTextContainer","multiplexStatus","fabricEvents","colorToIndex","startCoords","y","_clickCoords","rect","getBoundingClientRect","clientX","clientY","getPlates","selecting","coords","areas","_wellToCoords","_coordsToRect","_coordsToWell","shiftKey","_rectToArea","setSelection","endCoords","area","_areasToTiles","_setSelectedTiles","_setFocalWellRect","activeElement","blur","flag","locToAddress","r","c","addressAllowToEdit","setFieldsDisabled","_areaToRect","_wellToArea","focalWellRect","selectedTiles","_getSelectedWells","_getCommonFields","referenceWell","referenceFields","fields","refArr","agrArr","containsObject","inArray","obj","list","equality","evaluate","listKey","_getCommonWell","multiplexField","curMultipleVal","multipleVal","getDifferentWellsVals","wellsHash","wellId","differentWellsVals","commonWell","allFieldVal","fieldIdx","wellIdx","diffWellVal","curWellData","commonVal","curMultiVal","getWellSetAddressWithData","assets","interface","_createInterface","divIdentifier","topSection","topLeft","topRight","overLayContainer","_createOverLay","_createTabAtRight","_createTabs","_placePresetTabs","_setShortcuts","keyup","_handleShortcuts","_configureUndoRedoArray","addEventListener","copyCriteria","clearCriteria","preventDefault","pasteCriteria","keyCode","metaKey","redo","undo","loadPlate","sanitizeWell","sanitizeAreas","sanitized","setData","minCol","_coordIndex","maxCol","minRow","maxRow","max","_wellInArea","newWell","GET_PLATES","IS_READ_ONLY","IS_DISABLE_ADD_DELETE_WELL","GET_SELECTED_OBJECT","SETSELECTEDWELL","overlay","overLayButtonContainer","clearCriteriaButton","copyCriteriaButton","pasteCriteriaButton","undoButton","redoButton","hasWellUpdate","alert","widget","addressToLoc","layoutAddress","m","exec","toUpperCase","row_v","charCodeAt","locToIndex","t","addressToIndex","_rowKey","c1","c2","code","fromCharCode","indexToLoc","_create","numRows","numCols","component","className","isReadOnly","imgSrc","_init","addData","getTextDerivative","wellsData","textDerivative","textValWell","textFieldIdWell","textFieldVal","getWellsDifferences","isDisableAddDeleteWell","column_with_default_val","actionPointer","undoRedoArray","getSelectedObject","selectedObjects","getSelectedIndex","selectedObj","addressList","locMap","apply","preset","me","presets","wellAttrContainer","tabContainer","presetTabContainer","divText","title","presetButton","_selectPreset","allTabs","tabHead","tabIndex","_tabClickHandler","tabDataContainer","_addDataTabs","clickedTab","selectedTab","previouslyClickedTabIndex","clickedTabIndex","undoRedoManager","splice","shiftUndoRedo","pointerDiff","pointer","setUndoRedo","wellArea","reduce","tiles","_encodeArea","_encodeAreas","_decodeWell","wellAddress","match","adRx","RegExp","_decodeArea","areaAddress","split","_decodeAreas","areasAddress","abs","count","coord","center","hw","right","bottom"],"mappings":"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","file":"plate-map.min.js","sourcesContent":["var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.addDataOnChange = function() {\n // This object is invoked when something in the tab fields change\n return {\n\n _addAllData: function(data) {\n // Method to add data when something changes in the tabs. Its going to be tricky , just starting.\n if (this.allSelectedObjects) {\n var noOfSelectedObjects = this.allSelectedObjects.length;\n var wells = [];\n for (var objectIndex = 0; objectIndex < noOfSelectedObjects; objectIndex++) {\n var tile = this.allSelectedObjects[objectIndex];\n var well;\n if (tile.index in this.engine.derivative) {\n well = this.engine.derivative[tile.index];\n } else {\n well = $.extend(true, {}, this.defaultWell); \n this.engine.derivative[tile.index] = well; \n }\n var processedData = this.processWellData(data, well, noOfSelectedObjects, wells);\n wells = processedData.wells;\n well = processedData.well;\n var empty = this.engine.wellEmpty(well);\n if (empty) {\n if (this.emptyWellWithDefaultVal && this.disableAddDeleteWell) {\n var wellCopy = JSON.parse(JSON.stringify(well));\n var defaultValue = this.emptyWellWithDefaultVal;\n for (var key in defaultValue){\n if (key in wellCopy){\n wellCopy[key] = defaultValue[key];\n this._applyFieldData(key, defaultValue[key]);\n }\n }\n this.engine.derivative[tile.index] = wellCopy;\n } else {\n delete this.engine.derivative[tile.index];\n }\n }\n }\n }\n // update multiplex remove all field\n this._getAllMultipleVal(wells);\n this.applyFieldWarning(wells);\n // create well when default field is sent for the cases when user delete all fields during disabledNewDeleteWell mode\n this._colorMixer();\n this.derivativeChange();\n },\n\n processWellData: function(newData, curWell, noOfSelectedObjects, wellList) {\n\n if (!wellList){\n wellList = [];\n }\n for (var id in newData) {\n var v;\n if (newData[id] !== undefined && newData[id] !== null ) {\n if (newData[id].multi){\n var curData = newData[id];\n var preData = curWell[id];\n var newDt = this._getMultiData(preData, curData, id, noOfSelectedObjects);\n // need to replace newData\n v = JSON.parse(JSON.stringify(newDt));\n } else {\n v = JSON.parse(JSON.stringify(newData[id]));\n }\n } else {\n v = JSON.parse(JSON.stringify(newData[id]));\n }\n curWell[id] = v;\n wellList.push(curWell);\n }\n\n return {\n well: curWell,\n wells: wellList\n }\n },\n\n _getMultiData: function(preData, curData, fieldId, noOfSelectedObjects) {\n var addNew = curData.added;\n var removed = curData.removed;\n if (addNew) {\n if (preData){\n if (addNew.value) {\n var add = true;\n for (var listIdx in preData) {\n var multiplexData = preData[listIdx];\n // for cases when the add new data exist in well\n if (multiplexData[fieldId].toString() === addNew.id.toString()) {\n add = false;\n // update subfield value\n preData = preData.map(function(val) {\n if (val[fieldId].toString() === addNew.id.toString()) {\n for (var subFieldId in val) {\n // over write previous data if only one well is selected\n if (subFieldId in addNew.value && subFieldId !== fieldId){\n if (noOfSelectedObjects === 1) {\n val[subFieldId] = addNew.value[subFieldId];\n } else if (addNew.value[subFieldId]) {\n val[subFieldId] = addNew.value[subFieldId];\n }\n }\n }\n }\n return val;\n })\n }\n }\n if (add) {\n preData.push(addNew.value);\n }\n } else if (preData.indexOf(addNew) < 0) {\n preData.push(addNew);\n }\n } else {\n preData = [];\n if (addNew.value) {\n preData.push(addNew.value);\n } else if (addNew){\n preData.push(addNew);\n }\n }\n }\n\n var removeListIndex = function(preData, removeIndex) {\n var newPreData = [];\n for (var idx in preData) {\n if (parseInt(idx) !== parseInt(removeIndex)){\n newPreData.push(preData[idx]);\n }\n }\n return newPreData;\n };\n\n if (removed) {\n var removeIndex;\n // for multiplex field\n if (removed.value) {\n for (var listIdx in preData) {\n var multiplexData = preData[listIdx];\n if (multiplexData[fieldId].toString() === removed.id.toString()) {\n removeIndex = listIdx;\n }\n }\n // remove nested element\n preData = removeListIndex(preData, removeIndex);\n } else {\n if (preData){\n removeIndex = preData.indexOf(removed);\n if (removeIndex >= 0) {\n preData = removeListIndex(preData, removeIndex);\n }\n }\n }\n }\n if (preData && (preData.length == 0)) {\n preData = null; \n }\n return preData\n },\n\n _colorMixer: function() {\n if (!this.undoRedoActive) {\n var data = this.createObject();\n this.addToUndoRedo(data);\n }\n this.engine.searchAndStack(); \n this.engine.applyColors();\n this.mainFabricCanvas.renderAll();\n },\n\n derivativeChange: function(){\n this._trigger(\"updateWells\", null, this.createObject());\n },\n\n createObject: function() {\n var derivative = $.extend(true, {}, this.engine.derivative); \n var checkboxes = this.globalSelectedAttributes.slice(); \n var selectedAreas = this.selectedAreas.slice(); \n var focalWell = this.focalWell;\n\n return {\n \"derivative\": derivative,\n \"checkboxes\": checkboxes,\n \"selectedAreas\": selectedAreas,\n \"focalWell\": focalWell,\n \"requiredField\": this.requiredField\n };\n }\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.addDataToFields = function() {\n\n return {\n\n _addDataToTabFields: function(values) {\n // Configure how data is added to tab fields\n for (var id in values) {\n this._applyFieldData(id, values[id]);\n }\n },\n\n _applyFieldData: function(id, v) {\n this.fieldMap[id].setValue(v); \n }\n }\n }\n})(jQuery, fabric)","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.addTabData = function() {\n\n return {\n\n fieldList: [], \n fieldMap: {},\n autoId: 1,\n\n _addTabData: function() {\n // Here we may need more changes because attributes format likely to change\n var tabData = this.options.attributes.tabs;\n var that = this;\n this.requiredField = [];\n var multiplexFieldArray = [];\n tabData.forEach(function (tab, tabPointer) {\n if (tab[\"fields\"]) {\n var tabFields = tab[\"fields\"];\n var fieldArray = [];\n var fieldArrayIndex = 0;\n // Now we look for fields in the json\n for (var field in tabFields) {\n var data = tabFields[field];\n\n if (!data.id) {\n data.id = \"Auto\" + that.autoId++;\n console.log(\"Field autoassigned id \" + data.id);\n }\n if (!data.type) {\n data.type = \"text\";\n console.log(\"Field \" + data.id + \" autoassigned type \" + data.type);\n }\n\n var field_val;\n if (data.type === \"multiplex\") {\n field_val = that._makeMultiplexField(data, tabPointer, fieldArray);\n multiplexFieldArray.push(field_val);\n } else {\n field_val = that._makeRegularField(data, tabPointer, fieldArray, true);\n if (data.type === \"multiselect\") {\n multiplexFieldArray.push(field_val);\n }\n };\n }\n\n that.allDataTabs[tabPointer][\"fields\"] = fieldArray;\n } else {\n console.log(\"unknown format in field initialization\");\n }\n });\n that.multipleFieldList = multiplexFieldArray;\n },\n\n _makeSubField: function (data, tabPointer, fieldArray) {\n var that = this;\n if (!data.id) {\n data.id = \"Auto\" + that.autoId++;\n console.log(\"Field autoassigned id \" + data.id);\n }\n if (!data.type) {\n data.type = \"text\";\n console.log(\"Field \" + data.id + \" autoassigned type \" + data.type);\n }\n var wrapperDiv = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-default-field\");\n var wrapperDivLeftSide = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-left-side\");\n var wrapperDivRightSide = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-right-side\");\n var nameContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-name\").text(data.name);\n var fieldContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-container\");\n\n $(wrapperDivRightSide).append(nameContainer);\n $(wrapperDivRightSide).append(fieldContainer);\n $(wrapperDiv).append(wrapperDivLeftSide);\n $(wrapperDiv).append(wrapperDivRightSide);\n $(that.allDataTabs[tabPointer]).append(wrapperDiv);\n\n var field = {\n id: data.id,\n name: data.name,\n root: wrapperDiv,\n data: data,\n required: data.required || false\n };\n\n fieldArray.push(field);\n that.fieldMap[data.id] = field;\n\n return field;\n },\n\n _makeRegularField: function (data, tabPointer, fieldArray, checkbox){\n var that = this;\n var wrapperDiv = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-default-field\");\n var wrapperDivLeftSide = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-left-side\");\n var wrapperDivRightSide = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-right-side \");\n var nameContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-name\").text(data.name);\n var fieldContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-container\");\n\n wrapperDivRightSide.append(nameContainer);\n wrapperDivRightSide.append(fieldContainer);\n wrapperDiv.append(wrapperDivLeftSide);\n wrapperDiv.append(wrapperDivRightSide);\n that.allDataTabs[tabPointer].append(wrapperDiv);\n\n var field = {\n id: data.id,\n name: data.name,\n root: wrapperDiv,\n data: data,\n required: data.required\n };\n\n if (field.required) {\n that.requiredField.push(field.id);\n }\n\n fieldArray.push(field);\n that.fieldList.push(field);\n that.fieldMap[field.id] = field;\n\n // Adding checkbox\n if (checkbox) {\n that._addCheckBox(field);\n }\n that._createField(field);\n\n field.onChange = function () {\n var v = field.getValue();\n var data = {};\n data[field.id] = v;\n that._addAllData(data);\n };\n return field;\n },\n\n _makeMultiplexField: function (data, tabPointer, fieldArray) {\n var that = this;\n var wrapperDiv = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-default-field\");\n var wrapperDivLeftSide = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-left-side\");\n var wrapperDivRightSide = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-right-side \");\n var nameContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-name\").text(data.name);\n var fieldContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-container\");\n\n wrapperDivRightSide.append(nameContainer);\n wrapperDivRightSide.append(fieldContainer);\n wrapperDiv.append(wrapperDivLeftSide);\n wrapperDiv.append(wrapperDivRightSide);\n that.allDataTabs[tabPointer].append(wrapperDiv);\n\n var field = {\n id: data.id,\n name: data.name,\n root: wrapperDiv,\n data: data,\n required: data.required\n };\n\n fieldArray.push(field);\n that.fieldList.push(field);\n that.fieldMap[data.id] = field;\n\n var subFieldList = [];\n //create subfields\n var requiredSubField = [];\n for (var subFieldKey in data.multiplexFields) {\n var subFieldData = data.multiplexFields[subFieldKey];\n var subField = that._makeSubField(subFieldData, tabPointer, fieldArray);\n subFieldList.push(subField);\n\n // stores required subField\n if (subFieldData.required) {\n requiredSubField.push(subField.id);\n }\n }\n\n //store required field\n if (field.required || requiredSubField.length) {\n this.requiredField.push ({\n multiplexId: field.id,\n subFields: requiredSubField\n });\n }\n\n field.subFieldList = subFieldList;\n that._createField(field);\n that._addCheckBox(field);\n\n subFieldList.forEach(function (subfield) {\n subfield.mainMultiplexField = field;\n fieldArray.push(subfield);\n that._createField(subfield);\n that._addCheckBox(subfield);\n delete that.defaultWell[subfield.id];\n // overwrite subField setvalue\n subfield.onChange = function () {\n var v = subfield.getValue();\n var mainRefField = subfield.mainMultiplexField;\n var curId = mainRefField.singleSelectValue();\n //var curDataLs = mainRefField.detailData;\n var curVal = {};\n curVal[mainRefField.id] = curId;\n //append subfields\n curVal[subfield.id] = v;\n var returnVal = {\n id: curId,\n value: curVal\n };\n\n field._changeMultiFieldValue(returnVal, null);\n var curDataLs = mainRefField.detailData;\n if (curDataLs !== null) {\n curId = mainRefField.singleSelectValue(); \n curDataLs = curDataLs.map(function(curData) {\n if (curData[mainRefField.id] === curId) {\n curData[subfield.id] = v;\n }\n return curData;\n });\n }\n mainRefField.detailData = curDataLs;\n };\n\n });\n\n field.getValue = function(){\n var v = field.input.select2('data');\n if (v.length) {\n return v.map(function (i) {\n return i.id;\n });\n }\n return null;\n };\n\n return field;\n }\n }\n }\n\n})(jQuery, fabric);\n","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.addWarningMsg = function () {\n // For those check boxes associated with every field in the tab\n return {\n fieldWarningMsg: function (field, text, include) {\n var that = this;\n var imgId = \"fieldWarning\" + field.id;\n var img = $(\"<span>\").html(that._assets.warningImg).attr(\"id\", imgId).addClass(\"plate-field-warning-image\");\n //field.root.find(\".plate-setup-tab-name\").append('<img id=\"theImg\" src=\"theImg.png\" />')\n if (include) {\n if (field.root.find(\"#\" + imgId).length <= 0){\n field.root.find(\".plate-setup-tab-name\").text(\" \" + field.name);\n field.root.find(\".plate-setup-tab-name\").prepend(img);\n\n var popText = $(\"<div/>\").addClass(\"pop-out-text\");\n popText.text(text);\n field.root.find(\".plate-setup-tab-name\").append(popText);\n\n $(\"#\" + imgId).hover(function (e) {\n popText[0].style.display = 'flex';\n }, function () {\n popText.hide();\n });\n }\n\n\n } else {\n if (field.root.find(\"#\" + imgId).length > 0) {\n field.root.find(\".plate-setup-tab-name\").text(field.name);\n $(\"#\" + imgId).remove();\n }\n }\n },\n\n removeWarningMsg: function (field, text, include) {\n var that = this;\n var imgId = \"fieldWarning\" + field.id;\n var img = $(\"<span>\").html(that._assets.warningImg).attr(\"id\", imgId).addClass(\"plate-field-warning-image\");\n //field.root.find(\".plate-setup-tab-name\").append('<img id=\"theImg\" src=\"theImg.png\" />')\n if (include) {\n field.root.find(\".plate-setup-tab-name\").append(img);\n\n var popText = $(\"<div/>\").addClass(\"pop-out-text\");\n popText.text(text);\n field.root.find(\".plate-setup-tab-name\").append(popText);\n\n $(\"#\" + imgId).hover(function (e) {\n popText[0].style.display = 'inline-block';\n }, function () {\n popText.hide();\n });\n\n } else {\n $(\"#\" + imgId).remove();\n if (field.root.find(\"#\" + imgId).length > 0) {\n //field.root.find(\".plate-setup-tab-name\").remove(img);\n $(\"#\" + imgId).remove();\n }\n }\n },\n\n applyFieldWarning: function(wells) {\n var that = this;\n var req = 0;\n var fill = 0;\n var fieldData = {};\n that.fieldList.forEach(function(field){\n fieldData[field.id] = [];\n });\n wells.forEach(function(well){\n if (!that.engine.wellEmpty(well)){\n for (var fieldId in fieldData) {\n if (fieldId in well) {\n fieldData[fieldId].push(well[fieldId]);\n } else {\n fieldData[fieldId].push(null);\n }\n }\n }\n });\n for (var i = 0; i < that.fieldList.length; i++) {\n var field = that.fieldList[i];\n if (field.applyMultiplexSubFieldColor){\n field.applyMultiplexSubFieldColor(fieldData[field.id]);\n } else {\n if (field.required) {\n var include = false;\n fieldData[field.id].forEach(function(val){\n // for multiselect\n if (val instanceof Array) {\n if (val.length === 0) {\n include = true;\n }\n } else {\n if (val === null) {\n include = true;\n }\n }\n });\n //field.root.find(\".plate-setup-tab-name\").css(\"background\", color);\n that.fieldWarningMsg(field, \"required field\", include);\n }\n }\n }\n }\n }\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.bottomTable = function() {\n // for bottom table\n return {\n _bottomScreen: function() {\n this.bottomContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-bottom-container\");\n this.bottomTableContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-bottom-table-container\");\n this.bottomTable = this._createElement(\"<table></table>\").addClass(\"plate-setup-bottom-table\");\n this.bottomTableContainer.append(this.bottomTable);\n this.bottomContainer.append(this.bottomTableContainer);\n this.container.append(this.bottomContainer);\n },\n\n addBottomTableHeadings: function() {\n\n this.bottomRow = this._createElement(\"<tr></tr>\");\n\n var singleField = this._createElement(\"<th></th>\")\n .text(\"Group\");\n this.bottomRow.prepend(singleField);\n // Now we append all the captions at the place.\n this.bottomTable.empty();\n this.bottomTable.append(this.bottomRow);\n\n this.rowCounter = 1;\n\n for (var i = 0; i < this.globalSelectedAttributes.length; i++) {\n var attr = this.globalSelectedAttributes[i];\n var field = this.fieldMap[attr];\n var singleField = this._createElement(\"<th></th>\").text(field.name);\n this.bottomRow.append(singleField);\n this.rowCounter = this.rowCounter + 1;\n }\n\n this.adjustFieldWidth(this.bottomRow);\n },\n\n tileAttrText: function(tile, attr) {\n var well = this.engine.derivative[tile.index];\n var field = this.fieldMap[attr];\n return field.getText(well[attr]);\n },\n\n addBottomTableRow: function(color, singleStack) {\n var that = this;\n var modelTile = this.allTiles[singleStack[0]];\n var row = this._createElement(\"<tr></tr>\");\n var plateIdDiv = this._createElement(\"<td></td>\").addClass(\"plate-setup-bottom-id\");\n var numberText = this._createElement(\"<button/>\");\n numberText.addClass(\"plate-setup-color-text\");\n numberText.text(color);\n plateIdDiv.append(numberText);\n\n numberText.click(function(evt){\n var addressToSelect = singleStack.map(function(addressIdx){\n return that.indexToAddress(addressIdx)\n });\n if (evt.ctrlKey) {\n that.getSelectedAddress().forEach(function(val){\n if (addressToSelect.indexOf(val) < 0){\n addressToSelect.push(val);\n }\n })\n }\n that.setSelectedWell(addressToSelect);\n that._trigger(\"selectedWells\", null, {selectedAddress: that.getSelectedAddress()});\n });\n\n if (color > 0) {\n color = ((color - 1) % (this.colorPairs.length - 1)) + 1;\n }\n var colorStops = this.colorPairs[color];\n\n plateIdDiv.css(\"background\", \"linear-gradient(to right, \" + colorStops[0] + \" , \" + colorStops[1] + \")\");\n\n row.append(plateIdDiv);\n\n for (var i = 0; i < this.globalSelectedAttributes.length; i++) {\n var attr = this.globalSelectedAttributes[i];\n var text = this.tileAttrText(modelTile, attr);\n var dataDiv = this._createElement(\"<td></td>\").text(text);\n row.append(dataDiv);\n }\n this.bottomTable.append(row);\n this.adjustFieldWidth(row);\n },\n\n bottomForFirstTime: function() {\n this.addBottomTableHeadings();\n // This is executed for the very first time.. !\n var row = this._createElement(\"<tr></tr>\");\n\n var colorStops = this.colorPairs[0];\n var plateIdDiv = this._createElement(\"<td></td>\");\n plateIdDiv.css(\"background\", \"-webkit-linear-gradient(left, \" + colorStops[0] + \" , \" + colorStops[1] + \")\");\n row.append(plateIdDiv);\n this.bottomTable.append(row);\n this.createExportButton();\n },\n\n adjustFieldWidth: function(row) {\n\n var length = this.rowCounter;\n if ((length) * 150 > 1024) {\n row.css(\"width\", (length) * 152 + \"px\");\n }\n },\n\n downloadCSV: function(csv, filename) {\n var csvFile;\n var downloadLink;\n\n // CSV file\n csvFile = new Blob([csv], {\n type: \"text/csv\"\n });\n\n // Download link\n downloadLink = document.createElement(\"a\");\n\n // File name\n downloadLink.download = filename;\n\n // Create a link to the file\n downloadLink.href = window.URL.createObjectURL(csvFile);\n\n // Hide download link\n downloadLink.style.display = \"none\";\n\n // Add the link to DOM\n document.body.appendChild(downloadLink);\n\n // Click download link\n downloadLink.click();\n },\n\n exportData: function(format) {\n var data = [];\n var rows = document.querySelectorAll(\"table tr\");\n\n var colorLocMap = {};\n var colorLocIdxMap = this.engine.stackUpWithColor;\n var dim = this.getDimensions();\n var that = this;\n for (var colorIdx in colorLocIdxMap) {\n colorLocMap[colorIdx] = colorLocIdxMap[colorIdx].map(function (locIdx) {\n return that.indexToAddress(locIdx, dim);\n })\n }\n\n for (var i = 0; i < rows.length; i++) {\n var row = [],\n cols = rows[i].querySelectorAll(\"td, th\");\n\n for (var j = 0; j < cols.length; j++) {\n var v = \"\";\n if (cols[j].innerText) {\n if (format === \"csv\") {\n v = '\"' + cols[j].innerText.replace(/\"/g, '\"\"') + '\"';\n } else {\n v = cols[j].innerText;\n }\n }\n row.push(v);\n\n // add location column\n if (i === 0 && j === 0) {\n if (format === \"csv\") {\n row.push('\"Location\"');\n } else if (format === 'clipboard') {\n row.push(\"Location\");\n }\n\n }\n if (i !== 0 && j === 0) {\n var loc = '';\n if (colorLocMap[parseInt(cols[j].innerText)]) {\n if (format === \"csv\") {\n loc = '\"' + colorLocMap[parseInt(cols[j].innerText)].join(\",\") + '\"';\n } else if (format === 'clipboard') {\n loc = colorLocMap[parseInt(cols[j].innerText)].join(\",\");\n }\n }\n row.push(loc);\n }\n }\n\n if (format === \"csv\") {\n data.push(row.join(\",\"));\n } else if (format === 'clipboard') {\n data.push(row.join(\"\\t\"));\n //data.push(row); // for text type\n }\n\n }\n if (format === \"csv\") {\n // Download CSV file\n this.downloadCSV(data.join(\"\\n\"), 'table.csv');\n } else if (format === 'clipboard') {\n //return formatTableToString(data); // for text type\n return data.join(\"\\n\");\n }\n },\n\n createExportButton: function() {\n var that = this;\n var overlayContainer = $(\"<div>\").addClass(\"plate-setup-bottom-control-container\");\n\n var descriptionDiv = $(\"<div>\").addClass(\"plate-setup-overlay-text-container\");\n descriptionDiv.text(\"Color groups\");\n overlayContainer.append(descriptionDiv);\n\n var buttonContainer = $(\"<div>\").addClass(\"plate-setup-overlay-bottom-button-container\");\n\n // create export csv option\n var exportButton = $(\"<button/>\").addClass(\"plate-setup-button\");\n exportButton.text(\"Export CSV\");\n buttonContainer.append(exportButton);\n\n exportButton.click(function() {\n that.exportData('csv');\n exportButton.text(\"Exported\");\n exportButton[0].classList.remove(\"plate-setup-button\");\n exportButton.addClass(\"plate-setup-clicked-button\");\n setTimeout(resetExportText, 3000);\n });\n\n function resetExportText() {\n exportButton.text(\"Export CSV\");\n exportButton[0].classList.remove(\"plate-setup-clicked-button\");\n exportButton.addClass(\"plate-setup-button\");\n }\n\n // creat clipboard option, CLipboard is an external js file located in vendor/asset/javascripts\n var clipboardButton = $(\"<button/>\").addClass(\"plate-setup-button\");\n clipboardButton.text(\"Copy To Clipboard\");\n buttonContainer.append(clipboardButton);\n\n var clipboard = new ClipboardJS(clipboardButton.get(0), {\n text: function() {\n return that.exportData(\"clipboard\");\n }\n });\n\n clipboard.on('success', function(e) {\n clipboardButton.text(\"Copied as tab-delimited format\");\n clipboardButton[0].classList.remove(\"plate-setup-button\");\n clipboardButton.addClass(\"plate-setup-clicked-button\");\n setTimeout(resetClipboardText, 3000);\n });\n\n function resetClipboardText() {\n clipboardButton.text(\"Copy To Clipboard\");\n clipboardButton[0].classList.remove(\"plate-setup-clicked-button\");\n clipboardButton.addClass(\"plate-setup-button\");\n }\n\n clipboard.on('error', function(e) {\n clipboardButton.text(\"Failed to copy table to clipboard: browser may be incompatible\");\n setTimeout(resetClipboardText, 3000);\n });\n\n overlayContainer.append(buttonContainer);\n $(\".plate-setup-bottom-container\").prepend(overlayContainer);\n }\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.canvas = function() {\n //\n return {\n\n allSelectedObjects: null, // Contains all the selected objets, when click and drag.\n\n allPreviouslySelectedObjects: null,\n\n colorPointer: 0,\n\n goldenRatio: 0.618033988749895,\n\n _createCanvas: function() {\n this.normalCanvas = this._createElement(\"<canvas>\").attr(\"id\", \"DNAcanvas\");\n $(this.canvasContainer).append(this.normalCanvas);\n },\n\n _initiateFabricCanvas: function() {\n var w = this.canvasContainer.width(); \n var h = this.canvasContainer.height(); \n\n this._setCanvasArea(w, h);\n\n this.mainFabricCanvas = new fabric.Canvas('DNAcanvas', {\n backgroundColor: '#f5f5f5',\n selection: false,\n stateful: false,\n hoverCursor: \"pointer\",\n renderOnAddRemove: false,\n })\n .setWidth(w)\n .setHeight(h);\n },\n\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.checkBox = function() {\n // For those check boxes associated with every field in the tab\n return {\n\n globalSelectedAttributes: [],\n\n _addCheckBox: function(field) {\n var checkImage = $(\"<span>\").html(this._assets.dontImg).addClass(\"plate-setup-tab-check-box bg-light\")\n .data(\"clicked\", false);\n checkImage.data(\"linkedFieldId\", field.id);\n field.root.find(\".plate-setup-tab-field-left-side\").empty().append(checkImage);\n this._applyCheckboxHandler(checkImage); // Adding handler for change the image when clicked\n field.checkbox = checkImage;\n },\n\n _applyCheckboxHandler: function(checkBoxImage) {\n // We add checkbox handler here, thing is it s not checkbox , its an image and we change\n // source\n var that = this;\n checkBoxImage.click(function(evt, machineClick) {\n var checkBox = $(this);\n\n var changes = {};\n changes[checkBox.data(\"linkedFieldId\")] = !checkBox.data(\"clicked\");\n\n that.changeCheckboxes(changes);\n });\n },\n\n changeSubFieldsCheckboxes: function(field, changes) {\n var that = this;\n var subFieldToInclude = [];\n\n field.subFieldList.forEach(function(subField) {\n var checkImage = subField.checkbox;\n var fieldId = checkImage.data(\"linkedFieldId\");\n var clicked = checkImage.data(\"clicked\");\n if (fieldId in changes) {\n clicked = Boolean(changes[fieldId]);\n }\n checkImage.data(\"clicked\", clicked);\n if (clicked) {\n checkImage.html(that._assets.doImg);\n subFieldToInclude.push(subField.id);\n } else {\n checkImage.html(that._assets.dontImg);\n }\n });\n return subFieldToInclude;\n },\n\n changeCheckboxes: function(changes) {\n var gsa = [];\n var multiplexCheckedSubField = {};\n for (var i = 0; i < this.fieldList.length; i++) {\n var field = this.fieldList[i];\n if (field.checkbox) {\n if (field.subFieldList) {\n multiplexCheckedSubField[field.id] = this.changeSubFieldsCheckboxes(field, changes);\n }\n\n var checkImage = field.checkbox;\n var fieldId = checkImage.data(\"linkedFieldId\");\n var clicked = checkImage.data(\"clicked\");\n if (fieldId in changes) {\n clicked = Boolean(changes[fieldId]);\n }\n checkImage.data(\"clicked\", clicked);\n if (clicked) {\n gsa.push(fieldId);\n checkImage.html(this._assets.doImg);\n } else {\n checkImage.html(this._assets.dontImg);\n }\n }\n }\n this.globalSelectedMultiplexSubfield = multiplexCheckedSubField;\n this.globalSelectedAttributes = gsa;\n this._clearPresetSelection();\n this._colorMixer();\n },\n\n setSubFieldCheckboxes: function(field, fieldIds) {\n var that = this;\n var subFieldToInclude = [];\n field.subFieldList.forEach(function(subField) {\n var checkImage = subField.checkbox;\n var fieldId = checkImage.data(\"linkedFieldId\");\n var clicked = fieldIds.indexOf(fieldId) >= 0;\n checkImage.data(\"clicked\", clicked);\n if (clicked) {\n checkImage.html(that._assets.doImg);\n subFieldToInclude.push(subField.id);\n } else {\n checkImage.html(that._assets.dontImg);\n }\n });\n return subFieldToInclude;\n },\n\n setCheckboxes: function(fieldIds) {\n fieldIds = fieldIds || [];\n var gsa = [];\n var multiplexCheckedSubField = {};\n\n for (var i = 0; i < this.fieldList.length; i++) {\n var field = this.fieldList[i];\n if (field.checkbox) {\n // special handling for multiplex field\n if (field.subFieldList) {\n multiplexCheckedSubField[field.id] = this.setSubFieldCheckboxes(field, fieldIds);\n }\n\n var checkImage = field.checkbox;\n var fieldId = checkImage.data(\"linkedFieldId\");\n var clicked = fieldIds.indexOf(fieldId) >= 0;\n checkImage.data(\"clicked\", clicked);\n if (clicked) {\n gsa.push(fieldId);\n checkImage.html(this._assets.doImg);\n } else {\n\n checkImage.html(this._assets.dontImg);\n }\n }\n }\n this.globalSelectedMultiplexSubfield = multiplexCheckedSubField;\n this.globalSelectedAttributes = gsa;\n this._clearPresetSelection();\n this._colorMixer();\n }\n\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.colorManager = function() {\n\n return {\n // See these are color pairs for the gradient.\n colorPairs: [\n [\"#e6e6e6\", \"#808080\"],\n [\"#66e8ff\", \"#0082c8\"],\n [\"#ff7fb1\", \"#e6194b\"],\n [\"#a2ffb1\", \"#3cb44b\"],\n [\"#f784ff\", \"#911eb4\"],\n [\"#ffe897\", \"#f58231\"],\n [\"#6666ff\", \"#0000FF\"],\n [\"#ffff7f\", \"#ffe119\"],\n [\"#acffff\", \"#46f0f0\"],\n [\"#ff98ff\", \"#f032e6\"],\n [\"#ffffa2\", \"#d2f53c\"],\n [\"#ffffff\", \"#fabebe\"],\n [\"#66e6e6\", \"#008080\"],\n [\"#ffffff\", \"#e6beff\"],\n [\"#ffd48e\", \"#aa6e28\"],\n [\"#e66666\", \"#800000\"],\n [\"#ffffff\", \"#aaffc3\"],\n [\"#e6e666\", \"#808000\"],\n [\"#ffffff\", \"#ffd8b1\"],\n [\"#66a9ef\", \"#004389\"],\n [\"#ff6672\", \"#a7000c\"],\n [\"#66db72\", \"#00750c\"],\n [\"#b866db\", \"#520075\"],\n [\"#ffa966\", \"#b64300\"],\n [\"#ffff66\", \"#c0a200\"],\n [\"#6dffff\", \"#07b1b1\"],\n [\"#ff66ff\", \"#b100a7\"],\n [\"#f9ff66\", \"#93b600\"],\n [\"#ffe5e5\", \"#bb7f7f\"],\n [\"#66a7a7\", \"#004141\"],\n [\"#ffe5ff\", \"#a77fc0\"],\n [\"#d19566\", \"#6b2f00\"],\n [\"#ffffef\", \"#c0bb89\"],\n [\"#d1ffea\", \"#6bc084\"],\n [\"#a7a766\", \"#414100\"],\n [\"#ffffd8\", \"#c09972\"],\n [\"#a5ffff\", \"#3fc1ff\"],\n [\"#ffbef0\", \"#ff588a\"],\n [\"#e1fff0\", \"#7bf38a\"],\n [\"#ffc3ff\", \"#d05df3\"],\n [\"#ffffd6\", \"#ffc170\"],\n [\"#a5a5ff\", \"#3f3fff\"],\n [\"#ffffbe\", \"#ffff58\"],\n [\"#ebffff\", \"#85ffff\"],\n [\"#ffd7ff\", \"#ff71ff\"],\n [\"#a5ffff\", \"#3fbfbf\"],\n [\"#ffffcd\", \"#e9ad67\"],\n [\"#ffa5a5\", \"#bf3f3f\"],\n [\"#ffffa5\", \"#bfbf3f\"]\n ]\n }\n }\n\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.createCanvasElements = function() {\n // this class manages creating all the elements within canvas\n return {\n\n scaleFactor: 1, \n\n baseSizes: {\n spacing: 48, \n tile_radius: 22, \n center_radius_complete: 10, \n center_radius_incomplete: 14, \n label_size: 14, \n label_spacing: 24, \n text_size: 13,\n stroke: 0.5, \n gap: 2\n }, \n\n _setCanvasArea: function(w, h) {\n this.scaleFactor = Math.min(\n h / (this.dimensions.rows * this.baseSizes.spacing + this.baseSizes.label_spacing), \n w / (this.dimensions.cols * this.baseSizes.spacing + this.baseSizes.label_spacing));\n\n var sizes = {}\n for (var prop in this.baseSizes) {\n sizes[prop] = this.baseSizes[prop] * this.scaleFactor; \n }\n this.sizes = sizes; \n }, \n\n _canvas: function() {\n // Those 1,2,3 s and A,B,C s\n this._fixRowAndColumn();\n\n // All those circles in the canvas.\n this._putCircles();\n },\n\n _fixRowAndColumn: function() {\n var cols = this.dimensions.cols;\n var rows = this.dimensions.rows;\n\n var spacing = this.sizes.spacing;\n var d1 = this.sizes.label_spacing / 2;\n var d2 = this.sizes.label_spacing + this.sizes.spacing / 2; \n var fontSize = this.sizes.label_size; \n\n // For column\n var top = d1; \n var left = d2; \n for (var i = 1; i <= cols; i++) {\n var tempFabricText = new fabric.IText(i.toString(), {\n fill: 'black',\n originX: 'center',\n originY: 'center',\n fontSize: fontSize,\n top: top,\n left: left,\n fontFamily: '\"Roboto\", Arial, sans-serif',\n selectable: false,\n fontWeight: \"400\"\n });\n left += spacing; \n\n this.mainFabricCanvas.add(tempFabricText);\n }\n\n // for row\n top = d2; \n left = d1; \n for (var i = 1; i <= rows; i++) {\n var tempFabricText = new fabric.IText(this.rowIndex[i-1], {\n fill: 'black',\n originX: 'center',\n originY: 'center',\n fontSize: fontSize,\n top: top,\n left: left,\n fontFamily: '\"Roboto\", Arial, sans-serif',\n selectable: false,\n fontWeight: \"400\"\n });\n top += spacing; \n\n this.mainFabricCanvas.add(tempFabricText);\n }\n },\n\n _putCircles: function() {\n var cols = this.dimensions.cols;\n var rows = this.dimensions.rows;\n\n var tileCounter = 0;\n for (var row = 0; row < rows; row++) {\n for (var col = 0; col < cols; col++) {\n var index = this.allTiles.length; \n var tile = this._createTile(row, col); \n tile.index = tileCounter++; \n this.allTiles.push(tile);\n this.mainFabricCanvas.add(tile.background);\n this.mainFabricCanvas.add(tile.highlight);\n this.mainFabricCanvas.add(tile.circle);\n this.mainFabricCanvas.add(tile.circleCenter);\n this.mainFabricCanvas.add(tile.circleText);\n }\n }\n\n this._addLargeRectangleOverlay();\n this._fabricEvents();\n },\n\n _createTile: function (row, col) {\n var tile = {}; \n\n tile.visible = false; \n tile.colorIndex = null; \n tile.row = row; \n tile.col = col; \n tile.address = this.rowIndex[row] + (col + 1); \n\n var top = (row + 1) * this.sizes.spacing;\n var left = (col + 1) * this.sizes.spacing; \n\n tile.background = new fabric.Circle({\n top: top,\n left: left,\n radius: this.sizes.tile_radius,\n originX: 'center',\n originY: 'center',\n hasControls: false,\n hasBorders: false,\n lockMovementX: true,\n lockMovementY: true,\n evented: false,\n });\n\n tile.background.setGradient(\"fill\", {\n type: \"radial\",\n x1: this.sizes.tile_radius, \n x2: this.sizes.tile_radius, \n y1: this.sizes.tile_radius + this.sizes.gap,\n y2: this.sizes.tile_radius + this.sizes.gap,\n r1: this.sizes.tile_radius - this.sizes.gap,\n r2: this.sizes.tile_radius,\n colorStops: {\n 0: 'rgba(0,0,0,0.1)',\n 1: 'rgba(0,0,0,0.2)'\n }\n });\n\n tile.highlight = new fabric.Rect({\n originX: 'center',\n originY: 'center',\n top: top,\n left: left,\n width: this.sizes.spacing,\n height: this.sizes.spacing,\n fill: \"rgba(0,0,0,0.4)\",\n evented: false,\n visible: false\n });\n\n tile.circle = new fabric.Circle({\n originX: 'center',\n originY: 'center',\n top: top,\n left: left,\n radius: this.sizes.tile_radius,\n stroke: 'gray',\n strokeWidth: this.sizes.stroke,\n evented: false, \n visible: false\n });\n\n tile.circleCenter = new fabric.Circle({\n originX: 'center',\n originY: 'center',\n top: top,\n left: left,\n radius: this.sizes.center_radius_incomplete,\n fill: \"white\",\n stroke: 'gray',\n strokeWidth: this.sizes.stroke,\n evented: false,\n visible: false\n });\n\n tile.circleText = new fabric.IText(\"\", {\n originX: 'center',\n originY: 'center',\n top: top,\n left: left,\n fill: 'black',\n fontFamily: '\"Roboto\", Arial, sans-serif',\n fontSize: this.sizes.text_size,\n lockScalingX: true,\n lockScalingY: true,\n evented: false,\n visible: false\n });\n\n return tile; \n }, \n\n setTileComplete: function (tile, complete) {\n if (complete) {\n tile.circleCenter.radius = this.sizes.center_radius_complete;\n tile.circleText.fill = \"black\";\n tile.circleText.fontWeight = 'normal';\n } else {\n tile.circleCenter.radius = this.sizes.center_radius_incomplete;\n tile.circleText.fill = \"red\";\n tile.circleText.fontWeight = 'bold';\n }\n }, \n\n setTileVisible: function (tile, visible) {\n tile.visible = visible;\n tile.circle.visible = tile.visible;\n tile.circleCenter.visible = tile.visible;\n tile.circleText.visible = tile.visible;\n },\n\n setTileColor: function(tile, color, stackPointer) {\n this.setTileVisible(tile, true);\n tile.colorIndex = parseInt(color); \n tile.circleText.text = String(tile.colorIndex);\n\n if (color > 0) {\n color = ((color - 1) % (this.colorPairs.length -1)) + 1;\n }\n var colorStops = this.colorPairs[color];\n\n tile.circle.setGradient(\"fill\", {\n y2: 2 * this.sizes.tile_radius,\n colorStops: colorStops\n });\n },\n\n _addLargeRectangleOverlay: function() {\n\n this.overLay = new fabric.Rect({\n width: 632,\n height: 482,\n left: 0,\n top: 0,\n opacity: 0.0,\n originX: 'left',\n originY: 'top',\n lockMovementY: true,\n lockMovementX: true,\n selectable: false\n });\n\n this.mainFabricCanvas.add(this.overLay);\n }\n };\n }\n})(jQuery, fabric);\n","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.createField = function() {\n // It create those fields in the tab , there is 4 types of them.\n return {\n\n _createField: function(field) {\n switch (field.data.type) {\n case \"text\":\n this._createTextField(field);\n break;\n\n case \"numeric\":\n this._createNumericField(field);\n break;\n\n case \"select\":\n this._createSelectField(field);\n break;\n\n case \"multiselect\":\n this._createMultiSelectField(field);\n break;\n\n case \"boolean\":\n this._createBooleanField(field);\n break;\n\n case \"multiplex\":\n this._createMultiplexField(field);\n break;\n }\n },\n\n _createTextField: function(field) {\n var id = field.id;\n var that = this;\n var input = this._createElement(\"<input>\").attr(\"id\", id)\n .addClass(\"plate-setup-tab-input\");\n\n field.root.find(\".plate-setup-tab-field-container\").append(input);\n that.defaultWell[id] = null;\n\n field.parseValue = function(v) {\n if (v) {\n v = String(v);\n } else {\n v = null;\n }\n return v;\n };\n\n field.getValue = function() {\n var v = input.val().trim();\n if (v == \"\") {\n v = null;\n }\n return v;\n };\n\n field.setValue = function(v) {\n input.val(v);\n };\n\n field.getText = function(v) {\n if (v == null) {\n return \"\";\n }\n return v;\n };\n\n field.disabled = function(bool) {\n field.input.prop(\"disabled\", bool);\n };\n\n field.parseText = field.parseValue;\n\n input.on(\"input\", function(e, generated) {\n field.onChange();\n });\n\n field.input = input;\n },\n\n _createOpts: function(config) {\n var opts = {\n allowClear: true,\n placeholder: \"select\",\n minimumResultsForSearch: 10\n };\n\n if (config.options) {\n opts.data = config.options;\n } else if (config.query) {\n var query = config.query;\n if (config.delay) {\n query = this._debounce(config.delay, query);\n }\n opts.query = query;\n } else {\n throw \"Must specify data or query\";\n }\n return opts;\n },\n\n _createSelectField: function(field) {\n var id = field.id;\n var that = this;\n var input = this._createElement(\"<input/>\").attr(\"id\", id)\n .addClass(\"plate-setup-tab-select-field\");\n\n field.root.find(\".plate-setup-tab-field-container\").append(input);\n that.defaultWell[id] = null;\n\n var opts = that._createOpts(field.data);\n var optMap = {};\n opts.data.forEach(function(opt) {\n optMap[opt.id] = opt;\n });\n\n input.select2(opts);\n\n field.parseValue = function(value) {\n var v = value;\n\n if (v == \"\") {\n v = null;\n }\n if (v == null) {\n return null;\n }\n if (v in optMap) {\n return optMap[v].id;\n } else {\n throw \"Invalid value \" + value + \" for select field \" + id;\n }\n };\n\n field.disabled = function(bool) {\n field.input.prop(\"disabled\", bool);\n };\n\n field.getValue = function() {\n var v = input.select2('data');\n return v ? v.id : null;\n };\n\n field.setValue = function(v) {\n if (v) {\n v = optMap[v];\n }\n input.select2('data', v);\n };\n\n field.setOpts = function(v) {\n input.select2('data', {});\n opts.data = v || [];\n input.select2(opts);\n };\n\n field.getText = function(v) {\n if (v == null) {\n return \"\";\n }\n return optMap[v].text;\n };\n\n field.parseText = function(value) {\n var v = value;\n\n if (v == \"\") {\n v = null;\n }\n if (v == null) {\n return null;\n }\n if (v in optMap) {\n return optMap[v].text;\n } else {\n throw \"Invalid text value \" + value + \" for select field \" + id;\n }\n };\n\n input.on(\"change\", function(e, generated) {\n field.onChange();\n });\n\n field.input = input;\n },\n\n _createMultiSelectField: function(field) {\n var id = field.id;\n var that = this;\n var input = this._createElement(\"<input/>\").attr(\"id\", id)\n .addClass(\"plate-setup-tab-multiselect-field\");\n input.attr(\"multiple\", \"multiple\");\n\n field.root.find(\".plate-setup-tab-field-container\").append(input);\n that.defaultWell[id] = null;\n\n var separator = \",\";\n var opts = that._createOpts(field.data);\n opts.multiple = true;\n var optMap = {};\n opts.data.forEach(function(opt) {\n optMap[opt.id] = opt;\n });\n input.select2(opts);\n\n field.disabled = function(bool) {\n field.input.prop(\"disabled\", bool);\n };\n\n field.parseValue = function(value) {\n var v = value;\n if (v && v.length) {\n v = v.map(function(opt) {\n if (opt in optMap) {\n return optMap[opt].id;\n } else {\n throw \"Invalid value \" + opt + \" for multiselect field \" + id;\n }\n });\n } else {\n v = null;\n }\n return v;\n };\n\n field.setOpts = function(v) {\n var allOpts = field.data.options;\n var selectedVal = [];\n for (var id in allOpts) {\n var curOpts = allOpts[id];\n if (v.indexOf(curOpts[\"id\"]) >= 0) {\n selectedVal.push(curOpts);\n }\n }\n\n opts.data = selectedVal;\n input.select2(opts);\n };\n\n field.getValue = function() {\n var v = input.select2('data');\n if (v.length) {\n return v.map(function(i) {\n return i.id;\n });\n }\n return null;\n };\n\n field.setValue = function(v) {\n v = v || [];\n v = v.map(function(i) {\n return optMap[i];\n });\n input.select2('data', v);\n };\n\n field.getText = function(v) {\n if (v == null) {\n return \"\";\n }\n if (v.length > 0) {\n return v.map(function(v) {\n return optMap[v].text\n }).join(\"; \");\n }\n return \"\";\n };\n\n field.multiOnChange = function (added, removed) {\n if (added) {\n added = added.id.toString();\n }\n if (removed) {\n removed = removed.id.toString();\n }\n var data = {\n };\n data[field.id] = {\n multi: true,\n added: added,\n removed: removed\n };\n\n that._addAllData(data);\n };\n\n field.parseText = function(value){\n var v = value;\n if (v && v.length) {\n v = v.map(function(opt) {\n if (opt in optMap) {\n return optMap[opt].text;\n } else {\n throw \"Invalid text value \" + opt + \" for multiselect field \" + id;\n }\n });\n } else {\n v = null;\n }\n return v;\n };\n\n input.on(\"change\", function(e, generated) {\n var added = e.added;\n var removed = e.removed;\n //field.onChange();\n field.multiOnChange(added, removed);\n });\n\n field.input = input;\n\n that._createDeleteButton(field);\n },\n\n _createNumericField: function(field) {\n var id = field.id;\n var data = field.data;\n var that = this;\n var input = this._createElement(\"<input>\").addClass(\"plate-setup-tab-input\")\n .attr(\"placeholder\", data.placeholder || \"\").attr(\"id\", id);\n\n field.root.find(\".plate-setup-tab-field-container\").append(input);\n that.defaultWell[id] = null;\n\n // Adding unit\n var units = data.units || [];\n var defaultUnit = data.defaultUnit || null;\n var unitInput = null;\n if (defaultUnit) {\n if (units.length) {\n if (units.indexOf(defaultUnit) < 0) {\n defaultUnit = units[0];\n }\n } else {\n units = [defaultUnit];\n }\n } else {\n if (units.length) {\n defaultUnit = units[0];\n }\n }\n\n if (units.length) {\n field.units = units;\n field.hasUnits = true;\n field.defaultUnit = defaultUnit;\n if (units.length == 1) {\n var unitText = $(\"<div></div>\").addClass(\"plate-setup-tab-unit\");\n unitText.text(defaultUnit);\n field.root.find(\".plate-setup-tab-field-container\").append(unitText);\n } else {\n unitInput = this._createElement(\"<input/>\").attr(\"id\", id)\n .addClass(\"plate-setup-tab-label-select-field\");\n\n field.root.find(\".plate-setup-tab-field-container\").append(unitInput);\n\n var selected = null;\n var unitData = units.map(function(unit) {\n var o = {\n id: unit,\n text: unit\n };\n if (unit == defaultUnit) {\n selected = o;\n }\n return o;\n });\n\n var opts = {\n data: unitData,\n allowClear: false,\n minimumResultsForSearch: 10\n };\n\n unitInput.select2(opts);\n unitInput.select2(\"data\", selected);\n }\n }\n\n field.disabled = function(bool) {\n field.input.prop(\"disabled\", bool);\n if (unitInput) {\n unitInput.prop(\"disabled\", bool);\n }\n };\n\n field.setUnitOpts = function(opts) {\n field.units = opts || null;\n field.defaultUnit = null;\n\n var newUnits = [];\n var selected = null;\n if (field.units && field.units.length) {\n field.defaultUnit = field.units[0];\n newUnits = field.units.map(function(curUnit) {\n var cleanUnit = {\n id: curUnit,\n text: curUnit\n };\n if (curUnit == field.defaultUnit) {\n selected = cleanUnit;\n }\n return cleanUnit;\n });\n }\n\n var newOpts = {\n data: newUnits,\n allowClear: false,\n minimumResultsForSearch: 10\n };\n unitInput.select2(newOpts);\n unitInput.select2(\"data\", selected);\n };\n\n field.parseValue = function(value) {\n var v;\n if ($.isPlainObject(value)) {\n if (field.hasUnits) {\n v = field.parseRegularValue(value.value);\n if (v === null) {\n return null;\n }\n return {\n value: v,\n unit: field.parseUnit(value.unit)\n };\n } else {\n throw \"Value must be plain numeric for numeric field \" + id;\n }\n } else {\n if (field.hasUnits) {\n v = field.parseRegularValue(value);\n if (v === null) {\n return null;\n }\n return {\n value: v,\n unit: field.defaultUnit\n };\n } else {\n return field.parseRegularValue(value);\n }\n }\n };\n\n field.getValue = function() {\n var v = field.getRegularValue();\n\n if ((v === null) || isNaN(v)) {\n return null;\n } else if (field.hasUnits) {\n var returnVal = {\n value: v,\n unit: field.getUnit()\n };\n\n if (field.data.hasMultiplexUnit) {\n // include unitTypeId and UnitId to returnVal\n for (var unitTypeKey in field.data.unitMap) {\n var unitTypeUnits = field.data.unitMap[unitTypeKey];\n unitTypeUnits.forEach(function(unit) {\n if (unit.text === returnVal.unit) {\n returnVal['unitTypeId'] = unitTypeKey;\n returnVal['unitId'] = unit.id;\n }\n })\n }\n }\n return returnVal;\n } else {\n return v;\n }\n };\n\n field.setValue = function(value) {\n if (field.hasUnits) {\n if ($.isPlainObject(value)) {\n field.setUnit(value.unit || field.defaultUnit);\n field.setRegularValue(value.value);\n\n } else {\n field.setRegularValue(value);\n field.setUnit(field.defaultUnit)\n }\n } else {\n field.setRegularValue(value);\n }\n };\n\n field.parseRegularValue = function(value) {\n if (value == null) {\n return null;\n }\n var v = String(value).trim();\n if (v === \"\") {\n return null;\n }\n v = Number(value);\n if (isNaN(v)) {\n throw \"Invalid value \" + value + \" for numeric field \" + id;\n }\n return v;\n };\n\n field.getRegularValue = function() {\n var v = input.val().trim();\n if (v == \"\") {\n v = null;\n } else {\n v = Number(v);\n }\n return v;\n };\n\n field.setRegularValue = function(value) {\n input.val(value);\n };\n\n field.parseUnit = function(unit) {\n if (unit == null || unit === \"\") {\n return field.defaultUnit;\n }\n for (var i = 0; i < units.length; i++) {\n if (unit.toLowerCase() == units[i].toLowerCase()) {\n return units[i];\n }\n }\n throw \"Invalid unit \" + unit + \" for field \" + id;\n };\n\n field.getUnit = function() {\n if (unitInput) {\n return unitInput.val();\n } else {\n return field.defaultUnit;\n }\n };\n\n field.setUnit = function(unit) {\n if (unitInput) {\n unit = unit || field.defaultUnit;\n if (unit != null) {\n unit = {\n id: unit,\n text: unit\n };\n }\n unitInput.select2(\"data\", unit);\n }\n };\n\n // val now contains unit\n field.getText = function(val) {\n if (typeof(val) === 'object' && val) {\n var v = val.value;\n var u = val.unit;\n if (v == null) {\n return \"\";\n }\n v = v.toString();\n if (!u) {\n u = defaultUnit;\n }\n if (u) {\n v = v + \" \" + u;\n }\n return v;\n } else {\n return field.getRegularText(val);\n }\n };\n\n field.getRegularText = function(v) {\n if (v == null) {\n return \"\";\n }\n v = v.toString();\n return v;\n };\n\n field.parseText = function(v){\n var textVal = field.parseValue(v);\n if (textVal && typeof(textVal) === \"object\"){\n return textVal.value + textVal.unit;\n } else if (textVal) {\n return textVal\n } else {\n return null;\n }\n };\n\n input.on(\"input\", function() {\n var v = field.getRegularValue();\n if (isNaN(v)) {\n //flag field as invalid\n input.addClass(\"invalid\");\n } else {\n input.removeClass(\"invalid\");\n }\n field.onChange();\n });\n if (unitInput) {\n unitInput.on(\"change\", function() {\n field.onChange();\n });\n }\n\n field.input = input;\n field.unitInput = unitInput;\n },\n\n _createBooleanField: function(field) {\n var id = field.id;\n var that = this;\n var input = this._createElement(\"<input/>\").attr(\"id\", id)\n .addClass(\"plate-setup-tab-select-field\");\n that.defaultWell[id] = null;\n\n field.root.find(\".plate-setup-tab-field-container\").append(input);\n var tval = {\n id: \"true\",\n text: \"true\"\n };\n var fval = {\n id: \"false\",\n text: \"false\"\n };\n var opts = {\n data: [tval, fval],\n placeholder: \"select\",\n allowClear: true,\n minimumResultsForSearch: -1,\n initSelection: function(element, callback) {\n var v = element.val();\n callback({\n id: v,\n text: v\n });\n }\n };\n\n input.select2(opts);\n\n field.disabled = function(bool) {\n field.input.prop(\"disabled\", bool);\n };\n\n field.parseValue = function(value) {\n if (value == null) {\n return null;\n }\n var v = String(value).trim().toLowerCase();\n if (v == \"true\") {\n v = true;\n } else if (v == \"false\") {\n v = false;\n } else if (v == \"\") {\n v = null;\n } else {\n throw \"Invalid value \" + value + \" for boolean field \" + id;\n }\n return v;\n };\n\n field.getValue = function() {\n var v = input.val();\n switch (v) {\n case \"true\":\n return true;\n case \"false\":\n return false;\n default:\n return null;\n }\n };\n\n field.setValue = function(v) {\n if (v == true || v == \"true\") {\n v = tval;\n } else if (v == false || v == \"false\") {\n v = fval;\n } else {\n v = null;\n }\n input.select2('data', v);\n };\n\n field.getText = function(v) {\n if (v == null) {\n return \"\";\n }\n return v.toString();\n };\n\n field.parseText = field.parseValue;\n\n input.on(\"change\", function(e) {\n field.onChange();\n });\n\n field.input = input;\n },\n\n _createMultiplexField: function(field) {\n var that = this;\n // make correct multiplex data\n this._createMultiSelectField(field);\n // overwrite default well for multiplex field\n that.defaultWell[field.id] = [];\n\n // single select\n var nameContainer1 = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-name-singleSelect\").text(\"Select to edit\");\n var fieldContainer1 = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-container-singleSelect\");\n field.root.find(\".plate-setup-tab-field-right-side\").append(nameContainer1, fieldContainer1);\n\n field.singleSelect = this._createElement(\"<input/>\").attr(\"id\", field.id + \"SingleSelect\")\n .addClass(\"plate-setup-tab-multiplex-single-select-field\");\n\n field.singleSelect.appendTo(fieldContainer1);\n\n field.singleSelectValue = function () {\n var v = field.singleSelect.select2(\"data\");\n if (v != null) {\n v = v.id;\n }\n return v;\n };\n\n var setSingleSelectOptions = function (v, selected_v) {\n var opts = {\n allowClear: false,\n placeholder: \"select\",\n minimumResultsForSearch: 10,\n data: v || []\n }\n if (!selected_v) {\n if (opts.data.length) {\n selected_v = opts.data[0];\n } else {\n selected_v = null;\n }\n }\n field.singleSelect.select2('data', []);\n field.singleSelect.select2(opts);\n field.singleSelect.select2('data', selected_v);\n field.singleSelect.prop(\"disabled\", opts.data.length == 0);\n };\n\n var singleSelectChange = function () {\n var v = field.singleSelectValue();\n\n field.updateSubFieldUnitOpts(v);\n\n var curData = field.detailData || [];\n var curSubField = null;\n curData.forEach(function(val) {\n if (val[field.id] === v) {\n curSubField = val;\n }\n });\n\n if (curSubField) {\n // setvalue for subfield\n field.subFieldList.forEach(function(subField) {\n subField.disabled(false);\n subField.setValue(curSubField[subField.id]);\n });\n } else {\n field.subFieldList.forEach(function(subField) {\n subField.disabled(true);\n subField.setValue(null);\n });\n }\n that.readOnlyHandler();\n };\n\n setSingleSelectOptions([]);\n\n field.singleSelect.on(\"change\", singleSelectChange);\n\n field._changeMultiFieldValue = function(added, removed) {\n var newSubFieldValue = {};\n for (var subFieldName in field.data.multiplexFields) {\n var subFieldId = field.data.multiplexFields[subFieldName].id;\n newSubFieldValue[subFieldId] = null;\n }\n\n var val;\n if (added) {\n if (added.value) {\n val = added.value;\n } else {\n newSubFieldValue[field.id] = added.id;\n val = newSubFieldValue;\n }\n added = {\n id: added.id,\n value: val\n };\n }\n\n if (removed) {\n if (removed.value){\n val = removed.value;\n } else {\n newSubFieldValue[field.id] = removed.id;\n val = newSubFieldValue;\n }\n removed = {\n id: removed.id,\n value: val\n };\n }\n\n var data = {};\n data[field.id] = {\n multi: true,\n added: added,\n removed: removed\n };\n that._addAllData(data);\n };\n\n var multiselectSetValue = field.setValue;\n\n // overwrite multiplex set value\n field.setValue = function(v) {\n // used to keep track of initially loaded multiplex data\n field.detailData = v;\n var multiselectValues = null;\n if (v && v.length) {\n multiselectValues = v.map(function(val) {\n return val[field.id]\n });\n }\n\n multiselectSetValue(multiselectValues);\n var newOptions = field.input.select2('data') || [];\n setSingleSelectOptions(newOptions);\n singleSelectChange();\n };\n\n field.disabled = function(bool) {\n field.input.prop(\"disabled\", bool);\n field.subFieldList.forEach(function(subField) {\n subField.disabled(bool);\n });\n if (bool) {\n nameContainer1.text(\"Select to inspect\");\n } else {\n nameContainer1.text(\"Select to edit\");\n }\n };\n\n field.parseValue = function(value) {\n var v = value;\n if (v && v.length) {\n v = v.map(function(opt) {\n var valMap = {};\n valMap[field.id] = opt[field.id];\n for (var subFieldId in opt) {\n field.subFieldList.forEach(function(subField) {\n if (subField.id === subFieldId) {\n valMap[subField.id] = subField.parseValue(opt[subFieldId]);\n }\n });\n }\n return valMap;\n });\n } else {\n v = null;\n }\n return v;\n };\n\n field.updateSubFieldUnitOpts = function(val) {\n var curOpts;\n field.data.options.forEach(function(opt) {\n if (opt.id === val) {\n curOpts = opt;\n }\n });\n field.subFieldList.forEach(function(subField) {\n if (subField.data.hasMultiplexUnit) {\n if (curOpts && curOpts.hasOwnProperty(\"unitOptions\")) {\n\t\t\t\t\t\t\t\tsubField.setUnitOpts(curOpts.unitOptions[subField.id]);\n } else {\n subField.setUnitOpts(null);\n }\n }\n })\n };\n\n field.multiOnChange = function(added, removed) {\n field._changeMultiFieldValue(added, removed);\n var v = field.getValue();\n var curData = field.detailData;\n var curIds = [];\n var curOpt = null;\n //reshape data for saveback\n if (curData) {\n curIds = curData.map(function(val) {\n return val[field.id]\n });\n }\n\n var newMultiplexVal = [];\n var selectList = [];\n if (v) {\n v.forEach(function(selectedVal) {\n if (curData) {\n curData.forEach(function(val) {\n if (val[field.id] === selectedVal) {\n newMultiplexVal.push(val)\n }\n });\n }\n // cases when adding new data\n if (curIds.indexOf(selectedVal) < 0) {\n var newVal = {};\n newVal[field.id] = selectedVal;\n\n field.updateSubFieldUnitOpts(selectedVal);\n field.subFieldList.forEach(function(subfield) {\n // special handling for subfield which has multiplexUnit\n if (subfield.hasUnits) {\n if (subfield.data.hasMultiplexUnit) {\n subfield.disabled(false);\n field.data.options.forEach(function(opt) {\n if (opt.id === selectedVal) {\n var val = {\n value: null,\n unit: subfield.units[0]\n };\n newVal[subfield.id] = subfield.parseValue(val);\n }\n });\n } else {\n if (subfield.data.units) {\n if (subfield.data.units.length > 1){\n subfield.disabled(false);\n }\n }\n var val = {\n value: null,\n unit: subfield.defaultUnit\n };\n newVal[subfield.id] = subfield.parseValue(val);\n }\n }\n else {\n newVal[subfield.id] = subfield.parseValue(null);\n }\n });\n newMultiplexVal.push(newVal);\n }\n });\n\n // make data for single select options\n v.forEach(function(selectId) {\n field.data.options.forEach(function(opt) {\n if (opt.id === selectId) {\n selectList.push(opt);\n }\n });\n });\n // set the newest selected to be the current obj\n curOpt = selectList[v.length - 1];\n }\n\n field.detailData = newMultiplexVal;\n setSingleSelectOptions(selectList, curOpt);\n singleSelectChange();\n };\n\n field.getText = function(v) {\n if (v === null) {\n return \"\";\n }\n // get subfields that is selected from the checkbox\n if (field.id in that.globalSelectedMultiplexSubfield) {\n var checkedSubfields = that.globalSelectedMultiplexSubfield[field.id];\n var returnVal = [];\n for (var valIdx in v) {\n var subV = v[valIdx];\n var subText = [];\n for (var optId in field.data.options) {\n var opt = field.data.options[optId];\n if (opt.id === subV[field.id]) {\n subText.push(opt.text);\n }\n }\n field.subFieldList.forEach(function(subField) {\n if (checkedSubfields.indexOf(subField.id) >= 0) {\n var x = subField.getText(subV[subField.id]);\n subText.push(subField.name + \": \" + x);\n }\n });\n returnVal.push(\"{\" + subText.join(\", \") + \"}\");\n }\n return returnVal.join(\";\");\n }\n };\n\n field.parseText = function(v) {\n if (v === null) {\n return \"\";\n } else {\n var returnVal = [];\n for (var valIdx in v) {\n var subV = v[valIdx];\n var subText = [];\n for (var optId in field.data.options) {\n var opt = field.data.options[optId];\n if (opt.id === subV[field.id]) {\n subText.push(opt.text);\n }\n }\n field.subFieldList.forEach(function(subField) {\n var x = subField.getText(subV[subField.id]);\n if (x) {\n subText.push(x);\n }\n });\n returnVal.push(subText);\n }\n return returnVal;\n }\n };\n\n field.checkMultiplexCompletion = function(valList) {\n var valCount = 0;\n var completionPct = 0;\n var include = false;\n function getSubfieldStatus (vals) {\n var req = 0;\n var fill = 0;\n for (var subFieldId in field.subFieldList) {\n var subField = field.subFieldList[subFieldId];\n var curVal = vals[subField.id];\n if (subField.required) {\n include = true;\n req++;\n if (typeof(curVal) === 'object' && curVal) {\n if (curVal.value) {\n fill++;\n }\n } else if (curVal) {\n fill++;\n }\n }\n }\n return fill/req;\n }\n\n // for cases has value in multiplex field\n if (valList) {\n if (valList.length > 0){\n for (var idx in valList) {\n valCount++;\n var vals = valList[idx];\n completionPct += getSubfieldStatus(vals);\n }\n } else if (field.required) {\n include = true;\n valCount = 1;\n }\n } else if (field.required) {\n include = true;\n valCount = 1;\n }\n\n return {\n include: include,\n completionPct: completionPct/valCount\n };\n };\n\n // valList contains all of the vals for selected val\n field.applyMultiplexSubFieldColor = function(valList){\n function updateSubFieldWarningMap (vals) {\n for (var subFieldId in field.subFieldList) {\n var subField = field.subFieldList[subFieldId];\n // loop through each well's multiplexval list\n if (vals === null){\n if (field.required && subField.required){\n subFieldWarningMap[subField.id].warningStatus.push(true);\n }\n } else if (typeof(vals) === \"object\") {\n if (vals.length === 0) {\n if (field.required && subField.required){\n subFieldWarningMap[subField.id].warningStatus.push(true);\n }\n } else {\n for (var multiplexIdx in vals) {\n var curVal = vals[multiplexIdx][subField.id];\n if (subField.required) {\n if (typeof(curVal) === 'object' && curVal) {\n if (!curVal.value) {\n subFieldWarningMap[subField.id].warningStatus.push(true);\n } else {\n subFieldWarningMap[subField.id].warningStatus.push(false);\n }\n } else if (!curVal) {\n subFieldWarningMap[subField.id].warningStatus.push(true);\n } else {\n subFieldWarningMap[subField.id].warningStatus.push(false);\n }\n }\n }\n }\n }\n }\n }\n\n var subFieldWarningMap = {};\n field.subFieldList.forEach(function(subField){\n if (subField.required) {\n subFieldWarningMap[subField.id] = {\n field: subField,\n warningStatus: []\n };\n }\n });\n\n valList.forEach(function(multiplexVals) {\n updateSubFieldWarningMap(multiplexVals);\n });\n // turn off main field when all subfield are filled\n\n var requiredSubField = [];\n var mainFieldStatus = [];\n for (var subFieldId in subFieldWarningMap){\n var subField = subFieldWarningMap[subFieldId].field;\n if (subFieldWarningMap[subFieldId].warningStatus.indexOf(true) >= 0) {\n var text = subField.name + \" is a required subfield for \" + field.name + \", please make sure all \" + field.name + \" have \" + subField.name;\n if (field.required){\n that.fieldWarningMsg(subField, text, true);\n mainFieldStatus.push(true);\n } else {\n that.fieldWarningMsg(subField, text, true);\n mainFieldStatus.push(true);\n }\n } else {\n that.fieldWarningMsg(subField, \"none\", false);\n mainFieldStatus.push(false);\n }\n }\n var mainFieldWarning = false;\n if (mainFieldStatus.indexOf(true) < 0) {\n mainFieldWarning = false;\n } else {\n mainFieldWarning = true;\n }\n var warningText;\n if (field.required) {\n warningText = field.name + \" is a required field, please also fix missing required subfield(s) below\";\n } else {\n warningText = field.name + \" is not a required field, please fix missing required subfield(s) below or remove selected \" + field.name;\n }\n that.fieldWarningMsg(field, warningText, mainFieldWarning);\n };\n\n field.parseMainFieldVal = function(val) {\n var optMap = field.data.options;\n for (var idx = 0; idx < optMap.length; idx++){\n var curOpt = optMap[idx];\n if (curOpt.id === val){\n return curOpt.text\n }\n }\n };\n },\n\n _deleteDialog: function (field) {\n var that = this;\n\n var valMap = field.allSelectedMultipleVal;\n var valToRemove;\n if (valMap) {\n valToRemove = Object.keys(valMap);\n } else {\n valToRemove = [];\n }\n\n\n var dialogDiv = $(\"<div/>\").addClass(\"delete-dialog modal\");\n $('body').append(dialogDiv);\n\n function killDialog() {\n dialogDiv.hide();\n dialogDiv.remove();\n }\n\n var dialogContent = $(\"<div/>\").addClass(\"modal-content\").appendTo(dialogDiv);\n var tableArea = $(\"<div/>\").appendTo(dialogContent);\n var buttonRow = $(\"<div/>\").addClass(\"dialog-buttons\").css(\"justify-content\", \"flex-end\").appendTo(dialogContent);\n\n if (valToRemove.length > 0){\n // apply CSS property for table\n $(\"<p/>\").text(field.name + \" in selected wells: choose items to delete and click the delete button below\").appendTo(tableArea);\n\n var table = that._deleteDialogTable(field, valMap);\n table.appendTo(tableArea);\n table.addClass(\"plate-popout-table\");\n table.find('td').addClass(\"plate-popout-td\");\n table.find('th').addClass(\"plate-popout-th\");\n table.find('tr').addClass(\"plate-popout-tr\");\n if (!that.readOnly) {\n var deleteCheckedButton = $(\"<button class='multiple-field-manage-delete-button'>Delete Checked Items</button>\");\n buttonRow.append(deleteCheckedButton);\n deleteCheckedButton.click(function() {\n table.find(\"input:checked\").each(function () {\n var val = this.value;\n field.multiOnChange(null, {id: val});\n });\n // refresh selected fields after updating the multiplex field value\n that.decideSelectedFields();\n killDialog();\n });\n }\n\n } else {\n $(\"<p/>\").text(\"No \" + field.name + \" in the selected wells\").appendTo(tableArea);\n }\n\n var cancelButton = $(\"<button>Cancel</button>\");\n buttonRow.append(cancelButton);\n cancelButton.click(killDialog);\n\n dialogDiv.show();\n\n window.onclick = function(event) {\n if (event.target == dialogDiv[0]) {\n killDialog();\n }\n }\n },\n\n _deleteDialogTable: function (field, valMap) {\n var that = this;\n var colName = [field.name, \"Counts\"]; //Added because it was missing... no idea what the original should have been\n if (!that.readOnly) {\n colName.push(\"Delete\");\n }\n var table = $('<table/>');\n var thead = $('<thead/>').appendTo(table);\n var tr = $('<tr/>').appendTo(thead);\n\n tr.append(colName.map(function (text) {\n return $('<th/>').text(text);\n }));\n\n var tbody = $(\"<tbody/>\").appendTo(table);\n\n field.data.options.forEach(function (opt) {\n if (opt.id in valMap) {\n var tr = $('<tr/>').appendTo(tbody);\n var checkbox = $(\"<input type='checkbox'>\").prop(\"value\", opt.id);\n $(\"<td/>\").text(opt.text).appendTo(tr);\n $(\"<td/>\").text(valMap[opt.id]).appendTo(tr);\n if (!that.readOnly) {\n $(\"<td/>\").append(checkbox).appendTo(tr);\n }\n }\n });\n\n return table;\n },\n\n _createDeleteButton: function (field) {\n var that = this;\n var deleteButton = $(\"<button/>\").addClass(\"plate-setup-remove-all-button\");\n deleteButton.id = field.id + \"Delete\";\n deleteButton.text(\"Manage \" + field.name + \"...\");\n var buttonContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-remove-all-button-container\");\n buttonContainer.append(deleteButton);\n\n field.deleteButton = deleteButton;\n field.root.find(\".plate-setup-tab-field-right-side\").append(buttonContainer);\n\n deleteButton.click(function () {\n that._deleteDialog(field);\n });\n }\n\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.engine = function(THIS) {\n // Methods which look after data changes and stack up accordingly\n // Remember THIS points to plateLayOutWidget and 'this' points to engine\n // Use THIS to refer parent this.\n return {\n engine: {\n\n derivative: {},\n stackUpWithColor: {},\n stackPointer: 2,\n\n wellEmpty: function (well) {\n for (var prop in well) {\n var curVal = well[prop];\n if (curVal !== null && curVal !== undefined) {\n if (Array.isArray(curVal)) {\n if (curVal.length > 0) {\n return false;\n }\n } else {\n return false;\n }\n }\n }\n return true;\n },\n\n searchAndStack: function() {\n // This method search and stack the change we made.\n this.stackUpWithColor = {};\n this.stackPointer = 1;\n var derivativeJson = {};\n for (var idx in this.derivative) {\n var data = this.derivative[idx];\n var wellData = {};\n for (var i = 0; i < THIS.globalSelectedAttributes.length; i++) {\n var attr = THIS.globalSelectedAttributes[i]; \n\n if (attr in THIS.globalSelectedMultiplexSubfield){\n var selectedSubFields = THIS.globalSelectedMultiplexSubfield[attr];\n var newMultiplexVal = [];\n for (var multiplexIdx in data[attr]){\n var curMultiplexVals = data[attr][multiplexIdx];\n var newVal = {};\n newVal[attr] = curMultiplexVals[attr];\n selectedSubFields.forEach(function (subFieldId) {\n newVal[subFieldId] = curMultiplexVals[subFieldId];\n });\n newMultiplexVal.push(newVal);\n }\n wellData[attr] = newMultiplexVal;\n } else {\n if (data[attr] != null) {\n wellData[attr] = data[attr];\n }\n }\n }\n if ($.isEmptyObject(wellData)) {\n derivativeJson[idx] = null; \n } else {\n derivativeJson[idx] = JSON.stringify(wellData);\n }\n }\n\n while (!$.isEmptyObject(derivativeJson)) {\n var keys = Object.keys(derivativeJson).map(function (k) {return parseFloat(k, 10);});\n keys.sort(function (a, b) {return a-b;}); \n\n var refDerivativeIndex = keys[0];\n var referenceDerivative = derivativeJson[refDerivativeIndex];\n var arr = [];\n\n if (!referenceDerivative) {\n // if no checked box has value, push it to first spot\n if (this.stackUpWithColor[0]) {\n this.stackUpWithColor[0].push(refDerivativeIndex);\n } else {\n this.stackUpWithColor[0] = [refDerivativeIndex];\n }\n\n delete derivativeJson[refDerivativeIndex];\n } else {\n // if checked boxes have values\n for (var i = 0; i < keys.length; i++) {\n var idx = keys[i]; \n if (referenceDerivative == derivativeJson[idx]) {\n arr.push(idx);\n this.stackUpWithColor[this.stackPointer] = arr;\n delete derivativeJson[idx];\n }\n }\n if (arr.length > 0)\n this.stackPointer++;\n }\n }\n },\n\n applyColors: function() {\n\n var wholeNoTiles = 0;\n var wholePercentage = 0;\n\n THIS.addBottomTableHeadings();\n\n for (var i = 0; i < THIS.allTiles.length; i++) {\n var tile = THIS.allTiles[i];\n THIS.setTileVisible(tile, false);\n }\n\n for (var color = 0; color < this.stackPointer; color++) {\n var arr = this.stackUpWithColor[color];\n if (arr) {\n THIS.addBottomTableRow(color, arr);\n\n for (var tileIndex in arr) {\n wholeNoTiles++;\n var index = this.stackUpWithColor[color][tileIndex]; \n var tile = THIS.allTiles[index];\n var well = this.derivative[index];\n THIS.setTileColor(tile, color, this.stackPointer); \n // Checks if all the required fields are filled\n var completion = this.checkCompletion(well, tile);\n THIS.setTileComplete(tile, completion == 1); \n wholePercentage = wholePercentage + completion;\n }\n }\n }\n\n wholePercentage = Math.floor(100 * wholePercentage / wholeNoTiles);\n\n if (isNaN(wholePercentage)) {\n THIS.overLayTextContainer.text(\"Completion Percentage: 0%\");\n } else {\n THIS.overLayTextContainer.text(\"Completion Percentage: \" + wholePercentage + \"%\");\n }\n },\n\n checkCompletion: function(wellData, tile) {\n var req = 0; \n var fill = 0;\n for (var i = 0; i < THIS.fieldList.length; i++) {\n var field = THIS.fieldList[i];\n if (field.checkMultiplexCompletion){\n // also apply color\n var multiplexStatus = field.checkMultiplexCompletion(wellData[field.id]);\n if (multiplexStatus.include) {\n fill += multiplexStatus.completionPct;\n req++;\n }\n } else {\n if (field.required) {\n req++;\n if (wellData[field.id] !== null) {\n fill++;\n }\n }\n }\n }\n if (req === fill) {\n return 1; \n }\n return fill / req;\n },\n }\n }\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.fabricEvents = function() {\n // This object contains Menu items and how it works;\n return {\n colorToIndex: {},\n startCoords: {\n x: 0,\n y: 0\n },\n focalWell: {\n row: 0,\n col: 0\n },\n selectedAreas: [],\n\n _clickCoords: function(evt) {\n //Get XY Coords for a given event. \n var rect = evt.e.target.getBoundingClientRect();\n return {\n x: evt.e.clientX - rect.left,\n y: evt.e.clientY - rect.top\n };\n },\n\n _fabricEvents: function() {\n // Set up event handling. \n var that = this;\n\n $(that.target).on(\"getPlates\", function(evt, data) {\n // This method should be compatable to redo/undo.\n that.getPlates(JSON.parse(data));\n });\n\n that.mainFabricCanvas.on(\"mouse:down\", function(evt) {\n // Start selecting new area\n that.selecting = true;\n var coords = that._clickCoords(evt);\n\n var areas = that.selectedAreas.slice();\n var focalWell = that.focalWell;\n var startCoords = that._wellToCoords(focalWell, true);\n var rect = that._coordsToRect(startCoords, coords);\n\n if (evt.e.ctrlKey) {\n //adding new area\n startCoords = coords;\n rect = that._coordsToRect(startCoords, coords);\n focalWell = that._coordsToWell(startCoords);\n if (evt.e.shiftKey) {\n //replacing existing areas\n areas = [that._rectToArea(rect)];\n } else {\n areas.push(that._rectToArea(rect));\n }\n } else {\n if (evt.e.shiftKey) {\n //Altering last area\n areas[areas.length - 1] = that._rectToArea(rect);\n } else {\n //Creating new area\n startCoords = coords;\n rect = that._coordsToRect(startCoords, coords);\n focalWell = that._coordsToWell(startCoords);\n areas = [that._rectToArea(rect)];\n }\n }\n\n that.startCoords = startCoords;\n that.setSelection(areas, focalWell);\n that.mainFabricCanvas.renderAll();\n });\n\n that.mainFabricCanvas.on(\"mouse:move\", function(evt) {\n if (that.selecting) {\n // continue selecting new area\n var areas = that.selectedAreas.slice();\n var endCoords = that._clickCoords(evt);\n var rect = that._coordsToRect(that.startCoords, endCoords);\n var area = that._rectToArea(rect);\n if (area) {\n areas[areas.length - 1] = area;\n }\n\n that.setSelection(areas, that.focalWell);\n that.mainFabricCanvas.renderAll();\n }\n\n });\n\n that.mainFabricCanvas.on(\"mouse:up\", function(evt) {\n // finish selecting new area\n that.selecting = false;\n var areas = that.selectedAreas.slice();\n var endCoords = that._clickCoords(evt);\n var rect = that._coordsToRect(that.startCoords, endCoords);\n var area = that._rectToArea(rect);\n if (area) {\n areas[areas.length - 1] = area;\n }\n\n that.setSelection(areas, that.focalWell);\n that.decideSelectedFields();\n that.mainFabricCanvas.renderAll();\n that._trigger(\"selectedWells\", null, {selectedAddress: that.getSelectedAddress()});\n });\n },\n\n setSelection: function(areas, focalWell) {\n this.selectedAreas = areas;\n this.focalWell = focalWell;\n this.allSelectedObjects = this._areasToTiles(areas);\n this._setSelectedTiles();\n this._setFocalWellRect(this.focalWell);\n document.activeElement.blur();\n },\n\n _setFocalWellRect: function(well) {\n var flag;\n // check if not allow to add or delete existing wells\n if (this.disableAddDeleteWell) {\n var address = this.locToAddress({\n r: well.row,\n c: well.col\n });\n if (this.addressAllowToEdit.indexOf(address) < 0) {\n flag = false;\n this.setFieldsDisabled(true);\n } else {\n flag = true;\n this.setFieldsDisabled(false);\n }\n } else if (well) {\n flag = true;\n }\n\n if (flag) {\n var rect = this._areaToRect(this._wellToArea(well));\n var strokeWidth = 2;\n if (this.focalWellRect) {\n //update focalWellRect\n this.focalWellRect.top = rect.top;\n this.focalWellRect.left = rect.left;\n this.focalWellRect.width = rect.width - strokeWidth;\n this.focalWellRect.height = rect.height - strokeWidth;\n } else {\n //create focalWellRect\n this.focalWellRect = new fabric.Rect({\n width: rect.width - strokeWidth,\n height: rect.height - strokeWidth,\n left: rect.left,\n top: rect.top,\n fill: null,\n strokeWidth: strokeWidth,\n stroke: \"black\",\n selectable: false\n });\n this.mainFabricCanvas.add(this.focalWellRect);\n }\n } else {\n //clear focalWellRect\n this.mainFabricCanvas.remove(this.focalWellRect);\n this.focalWellRect = null;\n }\n },\n\n _setSelectedTiles: function() {\n // Update selected tile display only\n var selectedTiles = this.allSelectedObjects;\n this.allTiles.forEach(function(tile) {\n var selected = selectedTiles.indexOf(tile) >= 0;\n tile.highlight.visible = selected;\n })\n },\n\n _getSelectedWells: function () {\n var that = this; \n return this.allSelectedObjects.map(function (tile) {\n var well = that.engine.derivative[tile.index];\n if (!well) {\n well = that.defaultWell; \n }\n return well; \n }); \n },\n\n _getCommonFields: function (wells) {\n if (wells.length) {\n var referenceWell = wells[0];\n var referenceFields = $.extend(true, {}, referenceWell);\n for (var i = 1; i < wells.length; i++) {\n var fields = wells[i];\n for (var field in referenceFields) {\n if (Array.isArray(referenceFields[field])) {\n var refArr = referenceFields[field]; \n var agrArr = []; \n for (var j = 0; j < refArr.length; j++) {\n var v = refArr[j];\n if (v && typeof(v) === \"object\") {\n if (this.containsObject(v, fields[field])) {\n agrArr.push(v);\n }\n } else {\n if ($.inArray(v, fields[field]) >= 0) {\n agrArr.push(v);\n }\n }\n }\n referenceFields[field] = agrArr; \n } else {\n if (fields[field] && typeof(fields[field]) ===\"object\" && referenceFields[field] && typeof(referenceFields[field]) ===\"object\"){\n if ((fields[field].value !== referenceFields[field].value) || (fields[field].unit !== referenceFields[field].unit)){\n delete referenceFields[field];\n }\n } else if (referenceFields[field] != fields[field]) {\n delete referenceFields[field];\n }\n }\n }\n }\n return referenceFields\n } else {\n return {};\n }\n },\n\n containsObject: function(obj, list) {\n var equality = [];\n if (list) {\n list.forEach(function(val) {\n //evaluate val and obj\n var evaluate = [];\n Object.keys(val).forEach(function(listKey){\n if (Object.keys(obj).indexOf(listKey) >= 0){\n var curVal = val[listKey];\n if (typeof(curVal) === 'object' && curVal) {\n if (obj[listKey]){\n evaluate.push((curVal.unit === obj[listKey].unit) && (curVal.value === obj[listKey].value));\n } else {\n // when obj[listKey] is null but curVal is not\n evaluate.push(false);\n }\n } else {\n evaluate.push(curVal === obj[listKey]);\n }\n }\n });\n equality.push(evaluate.indexOf(false) < 0);\n });\n return equality.indexOf(true) >= 0;\n } else {\n return false;\n }\n },\n\n _getCommonWell: function (wells) {\n if (wells.length) {\n var referenceWell = wells[0];\n var referenceFields = $.extend(true, {}, referenceWell);\n for (var i = 1; i < wells.length; i++) {\n var well = wells[i];\n var fields = well;\n for (var field in referenceFields) {\n if (Array.isArray(referenceFields[field])) {\n var refArr = referenceFields[field]; \n var agrArr = []; \n for (var j = 0; j < refArr.length; j++) {\n var v = refArr[j];\n // for multiplex field\n if (typeof(refArr[j]) ===\"object\"){\n if (this.containsObject(v, fields[field])) {\n agrArr.push(v);\n }\n } else {\n if ($.inArray(v, fields[field]) >= 0) {\n agrArr.push(v);\n }\n }\n }\n referenceFields[field] = agrArr; \n } else {\n if (fields[field] && typeof(fields[field]) ===\"object\" && referenceFields[field] && typeof(referenceFields[field]) ===\"object\"){\n if ((fields[field].value !== referenceFields[field].value) || (fields[field].unit !== referenceFields[field].unit)){\n referenceFields[field] = null;\n }\n } else if (referenceFields[field] != fields[field]) {\n referenceFields[field] = null;\n }\n\n }\n }\n }\n return referenceFields;\n } else {\n return this.defaultWell; \n }\n }, \n\n _getAllMultipleVal: function (wells) {\n var multipleFieldList = this.multipleFieldList;\n\n multipleFieldList.forEach(function(multiplexField) {\n if(wells.length) {\n var curMultipleVal = {};\n wells.forEach(function (wellData) {\n var id = multiplexField.id;\n if (wellData[id]){\n if (wellData[id].length > 0) {\n wellData[id].forEach(function (multipleVal) {\n if (typeof(multipleVal) === 'object') {\n if (multipleVal[id] in curMultipleVal) {\n curMultipleVal[multipleVal[id]] ++;\n } else {\n curMultipleVal[multipleVal[id]] = 1;\n }\n } else {\n if (multipleVal in curMultipleVal) {\n curMultipleVal[multipleVal] ++;\n\n } else {\n curMultipleVal[multipleVal] = 1;\n }\n }\n })\n }\n }\n });\n multiplexField.allSelectedMultipleVal = curMultipleVal;\n } else {\n multiplexField.allSelectedMultipleVal = null\n }\n });\n },\n\n decideSelectedFields: function() {\n var wells = this._getSelectedWells();\n this._getAllMultipleVal(wells);\n this.applyFieldWarning(wells);\n var well = this._getCommonWell(wells); \n this._addDataToTabFields(well);\n },\n\n // get well value differences for each well in wellsHash\n getDifferentWellsVals: function(wellsHash) {\n var wells = [];\n for (var wellId in wellsHash){\n wells.push(wellsHash[wellId]);\n }\n var differentWellsVals = {};\n if (wells.length > 1){\n var commonWell = this._getCommonWell(wells);\n var allFieldVal = {};\n for (var fieldIdx in wellsHash[0]) {\n allFieldVal[fieldIdx] = [];\n }\n for (var wellIdx in wells){\n var diffWellVal = {};\n var curWellData = wells[wellIdx];\n for (var fieldId in curWellData) {\n var commonVal = commonWell[fieldId];\n var curVal = curWellData[fieldId];\n var newVal = null;\n if (Array.isArray(curVal)) {\n // get uncommonVal\n newVal = [];\n for (var idx = 0; idx < curVal.length; idx ++){\n var curMultiVal = curVal[idx];\n // multiplex field\n if (curMultiVal && typeof(curMultiVal === \"object\")){\n if (!this.containsObject(curMultiVal, commonVal)) {\n newVal.push(curMultiVal);\n if (!this.containsObject(curMultiVal, allFieldVal[fieldId])) {\n allFieldVal[fieldId].push(curMultiVal);\n }\n }\n } else {\n if (commonVal.indexOf(curMultiVal) >= 0) {\n newVal.push(curMultiVal);\n if (!allFieldVal[fieldId].indexOf(curMultiVal) >= 0) {\n allFieldVal[fieldId].push(curMultiVal);\n }\n }\n }\n }\n } else if (curVal && typeof(curVal) === \"object\"){\n if (commonVal && typeof(commonVal) ===\"object\"){\n if (!((curVal.value === commonVal.value) || (curVal.unit === commonVal.unit))){\n newVal = curVal;\n if (!this.containsObject(curVal, allFieldVal[fieldId])) {\n allFieldVal[fieldId].push(curVal);\n }\n }\n } else {\n newVal = curVal;\n if (!this.containsObject(curVal, allFieldVal[fieldId])) {\n allFieldVal[fieldId].push(curVal);\n }\n }\n } else if (curVal !== commonVal) {\n newVal = curVal;\n if (!allFieldVal[fieldId].indexOf(curVal) >= 0) {\n allFieldVal[fieldId].push(curVal);\n }\n }\n diffWellVal[fieldId] = newVal;\n }\n\n\n differentWellsVals[wellIdx] = diffWellVal;\n }\n\n // clean up step for fields that are empty\n for (var fieldId in allFieldVal) {\n if (allFieldVal[fieldId].length === 0) {\n for (var wellIdx in differentWellsVals){\n delete differentWellsVals[wellIdx][fieldId];\n }\n }\n }\n\n return differentWellsVals;\n } else if (wellsHash[0]) {\n var well = {};\n for (var fieldId in wellsHash[0]) {\n var curVal = wellsHash[0][fieldId];\n if (Array.isArray(curVal)){\n if (curVal.length > 0) {\n well[fieldId] = curVal\n }\n } else if (curVal){\n well[fieldId] = curVal;\n }\n }\n return {\n 0: well\n };\n }\n },\n\n // get all wells that has data\n getWellSetAddressWithData: function(){\n var address = [];\n var derivative = this.engine.derivative;\n for (var id in derivative){\n address.push(this.indexToAddress(id));\n }\n return address;\n }\n\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\nplateLayOutWidget.assets = function () {\n return {\n _assets: {\n doImg: '✓',\n dontImg: '',\n warningImg: '⚠'\n }\n };\n};\n","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.interface = function() {\n // interface holds all the methods to put the interface in place\n return {\n\n _createInterface: function() {\n\n var divIdentifier = '<div></div>';\n this.container = this._createElement(divIdentifier).addClass(\"plate-setup-wrapper\");\n this.topSection = this._createElement(divIdentifier).addClass(\"plate-setup-top-section\");\n\n this.topLeft = this._createElement(divIdentifier).addClass(\"plate-setup-top-left\");\n this.topRight = this._createElement(divIdentifier).addClass(\"plate-setup-top-right\");\n\n this.overLayContainer = this._createElement(divIdentifier).addClass(\"plate-setup-overlay-container\");\n this.canvasContainer = this._createElement(divIdentifier).addClass(\"plate-setup-canvas-container\");\n\n this._createOverLay();\n $(this.topLeft).append(this.overLayContainer);\n\n this._createCanvas();\n $(this.topLeft).append(this.canvasContainer);\n\n\n $(this.topSection).append(this.topLeft);\n $(this.topSection).append(this.topRight);\n\n $(this.container).append(this.topSection);\n $(this.element).append(this.container);\n\n this._initiateFabricCanvas();\n\n this._createTabAtRight();\n this._createTabs();\n\n this._placePresetTabs();\n // Bottom of the screen\n this._bottomScreen();\n // Canvas\n this._canvas();\n\n this.bottomForFirstTime();\n\n var that = this;\n this._setShortcuts();\n $(document.body).keyup(function(e) {\n that._handleShortcuts(e);\n });\n\n this._configureUndoRedoArray();\n },\n\n _createElement: function(element) {\n return $(element);\n },\n\n _setShortcuts: function () {\n var that = this; \n window.addEventListener(\"cut\", function (e) {\n if (document.activeElement == document.body) {\n that.copyCriteria();\n that.clearCriteria();\n e.preventDefault();\n }\n });\n window.addEventListener(\"copy\", function (e) {\n if (document.activeElement == document.body) {\n that.copyCriteria();\n e.preventDefault();\n }\n });\n window.addEventListener(\"paste\", function (e) {\n if (document.activeElement == document.body) {\n that.pasteCriteria();\n e.preventDefault();\n }\n });\n },\n\n _handleShortcuts: function(e) {\n if (document.activeElement === document.body) {\n if (e.keyCode == 46) {\n this.clearCriteria();\n e.preventDefault();\n } else if (e.ctrlKey || e.metaKey) {\n if (e.keyCode == 90) {\n if (e.shiftKey) {\n this.redo();\n } else {\n this.undo();\n }\n e.preventDefault();\n } else if (e.keyCode == 89) {\n this.redo();\n e.preventDefault();\n }\n }\n }\n },\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.loadPlate = function(THIS) {\n // Methods which look after data changes and stack up accordingly\n // Remember THIS points to plateLayOutWidget and 'this' points to engine\n return {\n\n getPlates: function (data) {\n //sanitize input\n var derivative = {}; \n for (var index in data.derivative) {\n var well = data.derivative[index]; \n derivative[index] = this.sanitizeWell(well); \n }\n\n var checkboxes = data.checkboxes || []; \n var selection = this.sanitizeAreas(data.selectedAreas, data.focalWell); \n\n var sanitized = {\n \"derivative\": derivative,\n \"checkboxes\": checkboxes,\n \"selectedAreas\": selection.selectedAreas,\n \"focalWell\": selection.focalWell\n }; \n\n this.setData(sanitized);\n }, \n\n sanitizeAreas: function (selectedAreas, focalWell) {\n var that = this; \n var rows = this.dimensions.rows;\n var cols = this.dimensions.cols;\n\n if (!selectedAreas) {\n selectedAreas = [];\n }\n if (selectedAreas.length) {\n selectedAreas = selectedAreas.map(function (area) {\n return {\n minCol: that._coordIndex(Math.min(area.minCol, area.maxCol), cols), \n minRow: that._coordIndex(Math.min(area.minRow, area.maxRow), rows), \n maxCol: that._coordIndex(Math.max(area.minCol, area.maxCol), cols), \n maxRow: that._coordIndex(Math.max(area.minRow, area.maxRow), rows)\n }; \n }); \n var area = selectedAreas[selectedAreas.length - 1];\n if (focalWell && !this._wellInArea(focalWell, area)) {\n focalWell = null;\n }\n if (!focalWell) {\n focalWell = {\n row: area.minRow,\n col: area.minCol\n };\n }\n } else {\n if (!focalWell) {\n focalWell = {\n row: 0,\n col: 0\n };\n }\n selectedAreas = [this._wellToArea(focalWell)];\n }\n return {\n selectedAreas: selectedAreas, \n focalWell: focalWell\n };\n }, \n\n sanitizeWell: function (well) {\n var newWell = {};\n for (var i = 0; i < this.fieldList.length; i++) {\n var field = this.fieldList[i];\n newWell[field.id] = field.parseValue(well[field.id]);\n }\n return newWell; \n }, \n\n setData: function(data) {\n this.engine.derivative = $.extend(true, {}, data.derivative);\n this.setCheckboxes(data.checkboxes);\n this.setSelection(data.selectedAreas, data.focalWell);\n this._colorMixer();\n this.decideSelectedFields();\n this.mainFabricCanvas.renderAll();\n },\n\n }\n }\n})(jQuery, fabric);","var GET_PLATES = 'getPlates';\nvar IS_READ_ONLY = 'isReadOnly';\nvar IS_DISABLE_ADD_DELETE_WELL = 'isDisableAddDeleteWell';\nvar GET_SELECTED_OBJECT = 'getSelectedObject';\nvar SETSELECTEDWELL = 'setSelectedWell';","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.overlay = function() {\n // overlay holds all the methods to put the part just above the canvas which contains all those\n // 'completion percentage' annd 'copy Criteria' button etc ...\n return {\n\n _createOverLay: function() {\n\n var that = this;\n this.overLayTextContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-overlay-text-container\");\n this.overLayTextContainer.text(\"Completion Percentage:\");\n this.overLayContainer.append(this.overLayTextContainer);\n this.overLayButtonContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-overlay-button-container\");\n this.overLayContainer.append(this.overLayButtonContainer);\n\n this.clearCriteriaButton = this._createElement(\"<button />\").addClass(\"plate-setup-button\");\n this.clearCriteriaButton.text(\"Clear\");\n this.overLayButtonContainer.append(this.clearCriteriaButton);\n\n this.clearCriteriaButton.click(function(evt) {\n that.clearCriteria();\n });\n\n this.copyCriteriaButton = this._createElement(\"<button />\").addClass(\"plate-setup-button\");\n this.copyCriteriaButton.text(\"Copy\");\n this.overLayButtonContainer.append(this.copyCriteriaButton);\n\n this.copyCriteriaButton.click(function(evt) {\n that.copyCriteria();\n });\n\n this.pasteCriteriaButton = this._createElement(\"<button />\").addClass(\"plate-setup-button\");\n this.pasteCriteriaButton.text(\"Paste\");\n this.overLayButtonContainer.append(this.pasteCriteriaButton);\n\n this.pasteCriteriaButton.click(function(evt) {\n that.pasteCriteria();\n });\n\n this.undoButton = this._createElement(\"<button />\").addClass(\"plate-setup-button\");\n this.undoButton.text(\"Undo\");\n this.overLayButtonContainer.append(this.undoButton);\n\n this.undoButton.click(function(evt) {\n that.undo();\n });\n\n this.redoButton = this._createElement(\"<button />\").addClass(\"plate-setup-button\");\n this.redoButton.text(\"Redo\");\n this.overLayButtonContainer.append(this.redoButton);\n\n this.redoButton.click(function(evt) {\n that.redo();\n });\n\n },\n\n clearCriteria: function() {\n if (this.allSelectedObjects) {\n var noOfSelectedObjects = this.allSelectedObjects.length;\n var hasWellUpdate = false;\n for (var objectIndex = 0; objectIndex < noOfSelectedObjects; objectIndex++) {\n var tile = this.allSelectedObjects[objectIndex];\n if (tile.index in this.engine.derivative) {\n // handling for clearing well when not allowed to add or delete wells\n if (this.emptyWellWithDefaultVal && this.disableAddDeleteWell) {\n var well = JSON.parse(JSON.stringify(this.defaultWell));\n var defaultValue = this.emptyWellWithDefaultVal;\n for (var key in defaultValue){\n if (key in well) {\n well[key] = defaultValue[key];\n this._applyFieldData(key, defaultValue[key]);\n } else {\n console.log(\"Well does not contain key: \" + key + \", please contact support\");\n }\n }\n this.engine.derivative[tile.index] = well;\n } else {\n delete this.engine.derivative[tile.index];\n }\n hasWellUpdate = true;\n }\n }\n if (hasWellUpdate){\n this.derivativeChange();\n }\n\n this._colorMixer();\n this.decideSelectedFields();\n } else {\n alert(\"Please select any well\");\n }\n },\n\n copyCriteria: function() {\n if (this.allSelectedObjects) {\n var wells = this._getSelectedWells(); \n this.commonWell = this._getCommonFields(wells); \n } else {\n alert(\"Please select any well.\");\n }\n },\n\n pasteCriteria: function() {\n if (this.commonWell) {\n this._addAllData(this.commonWell);\n this.decideSelectedFields();\n this.mainFabricCanvas.renderAll();\n }\n }\n };\n }\n})(jQuery, fabric);","$.widget(\"DNA.plateLayOut\", {\n\n plateLayOutWidget: {},\n\n options: {\n value: 0\n },\n\n allTiles: [], // All tiles containes all thise circles in the canvas\n\n addressToLoc: function (layoutAddress) {\n var m = /^([A-Z]+)(\\d+)$/.exec(layoutAddress.trim().toUpperCase())\n if (m) {\n var row_v = m[1]; \n var col = parseInt(m[2])-1;\n var row; \n for (var i = 0; i < row_v.length; i++) {\n var c = row_v.charCodeAt(i) - 65; \n if (i) {\n row += 1;\n row *= 26; \n row += c ; \n } else {\n row = c;\n }\n }\n return {\n r: row, \n c: col\n };\n } else {\n throw layoutAddress + \" not a proper layout address\"; \n }\n },\n\n locToIndex: function (loc, dimensions) {\n if (!dimensions) {\n dimensions = this.dimensions;\n }\n if (loc.r < 0) {\n t\n }\n if (!(loc.r >= 0 && loc.r < dimensions.rows)) {\n throw \"Row index \" + (loc.r + 1) + \" invalid\"; \n }\n if (!(loc.c >= 0 && loc.c < dimensions.cols)) {\n throw \"Column index \" + (loc.c + 1) + \" invalid\"; \n }\n return loc.r*dimensions.cols + loc.c; \n },\n\n addressToIndex: function (layoutAddress, dimensions) {\n var loc = this.addressToLoc(layoutAddress); \n return this.locToIndex(loc, dimensions); \n }, \n\n _rowKey: function (i) {\n var c1 = i % 26;\n var c2 = (i - c1) / 26;\n var code = String.fromCharCode(65 + c1);\n if (c2 > 0) {\n code = String.fromCharCode(64 + c2) + code;\n }\n return code;\n }, \n\n indexToLoc: function (index, dimensions) {\n if (!dimensions) {\n dimensions = this.dimensions;\n }\n\n if (index >= dimensions.rows * dimensions.cols) {\n throw \"Index too high: \" + index.toString(10); \n }\n var loc = {}; \n loc.c = index % dimensions.cols;\n loc.r = (index - loc.c) / dimensions.cols;\n\n return loc; \n },\n\n locToAddress: function (loc) {\n return this._rowKey(loc.r) + (loc.c + 1).toString(10);\n },\n\n indexToAddress: function (index, dimensions) {\n var loc = this.indexToLoc(index, dimensions); \n return this.locToAddress(loc); \n },\n\n getDimensions: function () {\n return $.extend(true, {}, this.dimensions);\n },\n\n _create: function() {\n var rows = parseInt(this.options.numRows || 8);\n var cols = parseInt(this.options.numCols || 12);\n this.dimensions = {\n rows: rows,\n cols: cols\n };\n this.rowIndex = [];\n for (var i = 0; i < rows; i++) {\n this.rowIndex.push(this._rowKey(i));\n }\n\n this.target = (this.element[0].id) ? \"#\" + this.element[0].id : \".\" + this.element[0].className;\n\n // Import classes from other files.. Here we import it using extend and add it to this\n // object. internally we add to widget.DNA.getPlates.prototype.\n // Helpers are methods which return other methods and objects.\n // add Objects to plateLayOutWidget and it will be added to this object.\n // set read only well\n if (this.options.readOnly){\n this.isReadOnly(true);\n }\n\n for (var component in plateLayOutWidget) {\n // Incase some properties has to initialize with data from options hash,\n // we provide it sending this object.\n $.extend(this, new plateLayOutWidget[component](this));\n }\n\n this.imgSrc = this.options.imgSrc || \"assets\";\n\n this._createInterface();\n\n this._trigger(\"created\", null, this);\n\n return this;\n },\n\n _init: function() {\n // This is invoked when the user use the plugin after _create is called.\n // The point is _create is invoked for the very first time and for all other\n // times _init is used.\n },\n\n addData: function() {\n alert(\"wow this is good\");\n },\n\n // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}}\n getTextDerivative: function(wellsData) {\n var textDerivative = {};\n var fieldMap = this.fieldMap;\n for (var idx in wellsData){\n var textValWell = {};\n var textFieldIdWell = {};\n var curWellData = wellsData[idx];\n for (var fieldId in curWellData){\n if (fieldId in this.fieldMap){\n var field = this.fieldMap[fieldId];\n var textVal = field.parseText(curWellData[fieldId]);\n textFieldIdWell[field.name] = textVal;\n textValWell[fieldId] = textVal;\n } else {\n // do not convert if not a field (ex: layout_address)\n textFieldIdWell[fieldId] = curWellData[fieldId];\n textValWell[fieldId] = curWellData[fieldId];\n }\n }\n textDerivative[idx] = {\n textVal: textValWell,\n textFieldVal: textFieldIdWell\n };\n }\n\n return textDerivative;\n },\n\n // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}}\n getWellsDifferences: function(wellsData) {\n return this.getDifferentWellsVals(wellsData);\n },\n\n setFieldsDisabled: function(flag){\n this.fieldList.forEach(function(field){\n field.disabled(flag);\n });\n },\n\n isReadOnly: function(flag){\n if (flag){\n this.readOnly = true;\n } else {\n this.readOnly = false;\n }\n this.readOnlyHandler();\n },\n\n readOnlyHandler: function(){\n if (this.readOnly){\n this.overLayButtonContainer.css(\"display\", \"none\");\n $('.multiple-field-manage-delete-button').css(\"display\", \"none\");\n this.setFieldsDisabled(true);\n } else {\n this.overLayButtonContainer.css(\"display\", \"flex\");\n $('.multiple-field-manage-delete-button').css(\"display\", \"none\");\n if (!this.disableAddDeleteWell) {\n this.setFieldsDisabled(false);\n }\n }\n },\n\n disableAddDeleteWell: null,\n // column_with_default_val will be used to determine empty wells, format: {field_name: default_val}\n isDisableAddDeleteWell: function(flag, column_with_default_val){\n if (flag){\n this.disableAddDeleteWell = true;\n this.addressAllowToEdit = this.getWellSetAddressWithData();\n // configure undo redo action\n this.actionPointer = 0;\n this.undoRedoArray = [];\n this.undoRedoArray.push(this.createObject());\n if (column_with_default_val) {\n this.emptyWellWithDefaultVal = column_with_default_val;\n }\n } else {\n this.disableAddDeleteWell = false;\n this.setFieldsDisabled(false);\n this.emptyWellWithDefaultVal = null;\n }\n this._fabricEvents();\n },\n\n getSelectedObject: function() {\n var selectedAddress = [];\n for (var i = 0; i < this.allSelectedObjects.length; i++){\n selectedAddress.push(this.allSelectedObjects[i].address);\n }\n var selectedObjects = {};\n var derivative = this.engine.derivative;\n for (var loc in derivative){\n var address = this.indexToAddress(loc);\n if (selectedAddress.indexOf(address) >= 0) {\n selectedObjects[address] = derivative[loc];\n }\n }\n return selectedObjects;\n },\n\n getSelectedIndex: function() {\n return this.allSelectedObjects.map(function(selectedObj){\n return that.addressToIndex(selectedObj.address)\n });\n },\n\n getSelectedAddress: function() {\n return this.allSelectedObjects.map(function(selectedObj){\n return selectedObj.address;\n });\n },\n\n setSelectedWell: function(addressList) {\n var areas = [];\n var minRow = 999;\n var locMap = {};\n for (var id = 0; id < addressList.length; id++){\n var wellIdx = this.addressToIndex(addressList[id]);\n var loc = this.indexToLoc(wellIdx);\n areas.push({\n minCol: loc.c,\n minRow: loc.r,\n maxCol: loc.c,\n maxRow: loc.r\n });\n if (loc.r <= minRow) {\n minRow = loc.r;\n if (loc.r in locMap) {\n locMap[loc.r].push(loc.c);\n } else {\n locMap[loc.r] = [loc.c];\n }\n }\n }\n var focalWell = {\n row: minRow,\n col: Math.min.apply(null, locMap[minRow])\n };\n\n this.setSelection(areas, focalWell);\n this.decideSelectedFields();\n this.mainFabricCanvas.renderAll();\n }\n\n});","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.preset = function(me) {\n // All the preset action goes here\n return {\n\n presets: [],\n\n _placePresetTabs: function() {\n var presets = this.options.attributes.presets;\n\n if (presets && presets.length) {\n this.wellAttrContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-well-attr-container\")\n .text(\"Checkbox presets\");\n this.tabContainer.append(this.wellAttrContainer);\n\n this.presetTabContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-preset-container\");\n this.tabContainer.append(this.presetTabContainer);\n\n for (var i = 0; i < presets.length; i++) {\n var preset = presets[i];\n var divText = this._createElement(\"<div></div>\").addClass(\"plate-setup-prest-tab-div\")\n .text(preset.title);\n\n var presetButton = this._createElement(\"<div></div>\").addClass(\"plate-setup-prest-tab\")\n .data(\"preset\", preset.fields).append(divText);\n this.presetTabContainer.append(presetButton);\n\n var that = this;\n presetButton.click(function() {\n var preset = $(this);\n that._selectPreset(preset);\n });\n this.presets.push(presetButton);\n }\n }\n },\n\n _clearPresetSelection: function() {\n for (var j = 0; j < this.presets.length; j++) {\n var p = this.presets[j]; \n p.removeClass(\"plate-setup-prest-tab-selected\")\n .addClass(\"plate-setup-prest-tab\"); \n }\n },\n\n _selectPreset: function (preset) {\n this.setCheckboxes(preset.data(\"preset\")); \n preset.removeClass(\"plate-setup-prest-tab\")\n .addClass(\"plate-setup-prest-tab-selected\");\n },\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.tabs = function() {\n // Tabs crete and manage tabs at the right side of the canvas.\n return {\n\n allTabs: [],\n\n defaultWell: {},\n\n allDataTabs: [], // To hold all the tab contents. this contains all the tabs and its elements and elements\n // Settings as a whole. its very usefull, when we have units for a specific field.\n // it goes like tabs-> individual field-> units and checkbox\n\n _createTabAtRight: function() {\n this.tabContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-tab-container\");\n $(this.topRight).append(this.tabContainer);\n },\n\n _createTabs: function() {\n // this could be done using z-index. just imagine few cards stacked up.\n // Check if options has tab data.\n // Originally we will be pulling tab data from developer.\n // Now we are building upon dummy data.\n this.tabHead = this._createElement(\"<div></div>\").addClass(\"plate-setup-tab-head\");\n $(this.tabContainer).append(this.tabHead);\n\n var tabData = this.options.attributes.tabs;\n var that = this;\n\n tabData.forEach(function (tab, tabIndex) {\n that.allTabs[tabIndex] = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab\");\n $(that.allTabs[tabIndex]).data(\"index\", tabIndex)\n .text(tab.name);\n\n $(that.allTabs[tabIndex]).click(function() {\n that._tabClickHandler(this);\n });\n\n $(that.tabHead).append(that.allTabs[tabIndex]);\n }); \n\n this.tabDataContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-tab-data-container\");\n $(this.tabContainer).append(this.tabDataContainer);\n\n this._addDataTabs(tabData);\n\n $(this.allTabs[0]).click();\n\n this._addTabData();\n },\n\n _tabClickHandler: function(clickedTab) {\n\n if (this.selectedTab) {\n $(this.selectedTab).removeClass(\"plate-setup-tab-selected\")\n .addClass(\"plate-setup-tab\");\n\n var previouslyClickedTabIndex = $(this.selectedTab).data(\"index\");\n $(this.allDataTabs[previouslyClickedTabIndex]).css(\"z-index\", 0);\n this.readOnlyHandler();\n }\n\n $(clickedTab).addClass(\"plate-setup-tab-selected\");\n\n this.selectedTab = clickedTab;\n\n var clickedTabIndex = $(clickedTab).data(\"index\");\n $(this.allDataTabs[clickedTabIndex]).css(\"z-index\", 1000);\n },\n\n _addDataTabs: function(tabs) {\n\n var tabIndex = 0;\n\n for (var tabData in tabs) {\n this.allDataTabs[tabIndex++] = this._createElement(\"<div></div>\").addClass(\"plate-setup-data-div\")\n .css(\"z-index\", 0);\n $(this.tabDataContainer).append(this.allDataTabs[tabIndex - 1]);\n }\n }\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.undoRedoManager = function(THIS) {\n\n return {\n\n undoRedoArray: [],\n\n actionPointer: null,\n\n addToUndoRedo: function(data) {\n\n if (this.actionPointer != null) {\n var i = this.actionPointer + 1; \n if (i < this.undoRedoArray.length) {\n this.undoRedoArray.splice(i, this.undoRedoArray.length - i);\n }\n }\n this.actionPointer = null;\n this.undoRedoArray.push($.extend(true, {}, data));\n },\n\n _configureUndoRedoArray: function() {\n\n var data = {\n checkboxes: [],\n derivative: {},\n selectedAreas: [{\n minRow: 0,\n minCol: 0,\n maxRow: 0,\n maxCol: 0\n }],\n focalWell: {\n row: 0,\n col: 0\n }\n };\n\n this.undoRedoArray = []; \n this.actionPointer = null; \n this.undoRedoArray.push($.extend({}, data));\n },\n\n undo: function() {\n console.log(\"undo\");\n return this.shiftUndoRedo(-1); \n },\n\n redo: function() {\n console.log(\"redo\");\n return this.shiftUndoRedo(1); \n }, \n\n shiftUndoRedo: function (pointerDiff) {\n var pointer = this.actionPointer;\n if (pointer == null) {\n pointer = this.undoRedoArray.length - 1; \n }\n pointer += pointerDiff; \n return this.setUndoRedo(pointer); \n }, \n\n setUndoRedo: function (pointer) {\n if (pointer < 0) {\n return false; \n }\n if (pointer >= this.undoRedoArray.length) {\n return false; \n }\n this.undoRedoActive = true; \n this.setData(this.undoRedoArray[pointer]);\n this.actionPointer = pointer; \n this.undoRedoActive = false;\n this.derivativeChange();\n return true;\n }\n }\n };\n\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.wellArea = function(fabric) {\n\n return {\n\n _areasToTiles: function(areas) {\n //Convert areas to tiles\n var cols = this.dimensions.cols;\n var that = this;\n return areas.reduce(function(tiles, area) {\n if (area) {\n for (var r = area.minRow; r <= area.maxRow; r++) {\n for (var c = area.minCol; c <= area.maxCol; c++) {\n var tile = that.allTiles[c + cols * r];\n if (tiles.indexOf(tile) < 0) {\n if (that.disableAddDeleteWell){\n if(that.addressAllowToEdit.indexOf(tile.address) >= 0){\n tiles.push(tile);\n }\n } else {\n tiles.push(tile);\n }\n }\n }\n }\n }\n return tiles;\n }, []);\n },\n\n _encodeArea: function(area) {\n //Encode area as string\n if ((area.minRow == area.maxRow) && (area.minCol == area.maxCol)) {\n return this.rowIndex[area.minRow] + area.minCol.toString(10);\n } else {\n return this.rowIndex[area.minRow] + area.minCol.toString(10) + \":\" + this.rowIndex[area.maxRow] + area.maxCol.toString(10);\n }\n },\n\n _encodeAreas: function(areas) {\n //Encode an array of areas as a string\n var that = this;\n return areas.map(function(area) {\n return that._encodeArea(area);\n }).join(\",\");\n },\n\n _decodeWell: function(wellAddress) {\n var that = this;\n var adRx = new RegExp(\"^\\\\s*(\" + that.rowIndex.join(\"|\") + \")(\\\\d+)\\\\s*$\")\n var rcRx = /^\\s*R(\\d+)C(\\d+)\\s*$/i;\n\n var match;\n match = wellAddress.match(adRx);\n if (match) {\n var row = that.rowIndex.indexOf(match[1]);\n if (row >= 0) {\n return {\n row: row,\n col: parseInt(match[2]) - 1\n };\n }\n }\n match = wellAddress.match(rcRx);\n if (match) {\n return {\n row: parseInt(match[1]) - 1,\n col: parseInt(match[2]) - 1\n };\n }\n\n throw \"Invalid well address: \" + wellAddress;\n },\n\n _decodeArea: function(areaAddress) {\n //Decode single area as string\n var that = this;\n var wells = areaAddress.split(\":\").map(function(wellAddress) {\n return that._decodeWell(wellAddress);\n })\n if (wells.length == 1) {\n return {\n minRow: wells[0].row,\n minCol: wells[0].col,\n maxRow: wells[0].row,\n maxCol: wells[0].col\n }\n } else if (wells.length == 2) {\n var minRow = Math.min(wells[0].row, wells[1].row)\n return {\n minRow: Math.min(wells[0].row, wells[1].row),\n minCol: Math.min(wells[0].col, wells[1].col),\n maxRow: Math.max(wells[0].row, wells[1].row),\n maxCol: Math.max(wells[0].col, wells[1].col)\n }\n } else {\n throw \"Invalid address: \" + areaAddress;\n }\n },\n\n _decodeAreas: function(areasAddress) {\n //Decode single area as string\n var that = this;\n return areasAddress.split(\",\").map(function(areaAddress) {\n return that._decodeArea(areaAddress);\n });\n },\n\n _wellToArea: function(well) {\n //Convert a well to an area\n return {\n minCol: well.col,\n minRow: well.row,\n maxCol: well.col,\n maxRow: well.row\n }\n },\n\n _wellInArea: function(well, area) {\n //Determine if a well lies within an area\n return well.row >= area.minRow && well.row <= area.maxRow && well.col >= area.minCol && well.col <= area.maxCol;\n },\n\n _coordsToRect: function(startCoords, endCoords) {\n //Convert two XY coords to a bounding box\n var left = Math.min(startCoords.x, endCoords.x);\n var top = Math.min(startCoords.y, endCoords.y);\n var height = Math.abs(endCoords.y - startCoords.y);\n var width = Math.abs(endCoords.x - startCoords.x);\n return {\n top: top,\n left: left,\n height: height,\n width: width\n };\n },\n\n _coordIndex: function(v, count) {\n var i;\n if (v < 0) {\n i = 0;\n } else if (v >= count) {\n i = count - 1;\n } else {\n i = Math.floor(v);\n }\n return i;\n },\n\n _coordsToWell: function(coord) {\n //Convert a coordinate to a well\n var cols = this.dimensions.cols;\n var rows = this.dimensions.rows;\n\n var w = this.sizes.spacing; \n var m = this.sizes.label_spacing; \n\n var x = (coord.x - m) / w;\n var y = (coord.y - m) / w;\n\n var row = this._coordIndex(y, rows);\n var col = this._coordIndex(x, cols);\n\n return {\n row: row,\n col: col,\n };\n },\n\n _wellToCoords: function(well, center) {\n //Convert a well to a coordinate\n var w = this.sizes.spacing; \n var m = this.sizes.label_spacing; \n var x = well.col * w + m;\n var y = well.row * w + m;\n if (center) {\n var hw = w/2;\n x = x + hw;\n y = y + hw;\n }\n\n return {\n x: x,\n y: y\n };\n },\n\n _areaToRect: function(area) {\n //Convert area to rectangle\n var rows = area.maxRow - area.minRow + 1;\n var cols = area.maxCol - area.minCol + 1;\n\n var w = this.sizes.spacing; \n var m = this.sizes.label_spacing; \n\n return {\n top: area.minRow * w + m,\n left: area.minCol * w + m,\n height: rows * w,\n width: cols * w\n }\n },\n\n _rectToArea: function(rect) {\n //Convert a rectangular region to an area\n var rows = this.dimensions.rows;\n var cols = this.dimensions.cols;\n\n var w = this.sizes.spacing; \n var m = this.sizes.label_spacing; \n\n var left = (rect.left - m) / w;\n var top = (rect.top - m) / w;\n var height = rect.height / w;\n var width = rect.width / w;\n var right = left + width;\n var bottom = top + height;\n\n //select whole row\n if (right < 0) {\n right = cols;\n }\n if (left >= cols) {\n left = 0;\n }\n //select whole col\n if (bottom < 0) {\n bottom = rows;\n }\n if (top <= 0) {\n top = 0;\n }\n\n return {\n minCol: this._coordIndex(left, cols),\n minRow: this._coordIndex(top, rows),\n maxCol: this._coordIndex(right, cols),\n maxRow: this._coordIndex(bottom, rows)\n };\n }\n\n }\n }\n})(jQuery, fabric);"]} \ No newline at end of file diff --git a/src/js/bottom-table.js b/src/js/bottom-table.js index f6c46a1..c728ea6 100755 --- a/src/js/bottom-table.js +++ b/src/js/bottom-table.js @@ -264,7 +264,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; }); overlayContainer.append(buttonContainer); - $(".plate-setup-bottom-container").prepend(overlayContainer); + this.bottomContainer.prepend(overlayContainer); } }; } diff --git a/src/js/engine.js b/src/js/engine.js index b543e8d..35316cd 100755 --- a/src/js/engine.js +++ b/src/js/engine.js @@ -10,6 +10,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; engine: { derivative: {}, + colorMap: new Map(), stackUpWithColor: {}, stackPointer: 2, @@ -121,7 +122,8 @@ var plateLayOutWidget = plateLayOutWidget || {}; var index = this.stackUpWithColor[color][tileIndex]; var tile = THIS.allTiles[index]; var well = this.derivative[index]; - THIS.setTileColor(tile, color, this.stackPointer); + this.colorMap.set(index, color); + THIS.setTileColor(tile, color); // Checks if all the required fields are filled var completion = this.checkCompletion(well, tile); THIS.setTileComplete(tile, completion == 1); diff --git a/src/js/example.js b/src/js/example.js index 82c7141..4080092 100644 --- a/src/js/example.js +++ b/src/js/example.js @@ -194,6 +194,7 @@ window.onload = function () { numRows: 8, numCols: 12, attributes: attributes, + // scrollToGroup: false, // optional updateWells: function (event, data) { //data has changed diff --git a/src/js/fabric-events.js b/src/js/fabric-events.js index e86d5b0..589b2fa 100755 --- a/src/js/fabric-events.js +++ b/src/js/fabric-events.js @@ -105,6 +105,9 @@ var plateLayOutWidget = plateLayOutWidget || {}; that.decideSelectedFields(); that.mainFabricCanvas.renderAll(); that._trigger("selectedWells", null, {selectedAddress: that.getSelectedAddress()}); + if(that.options.scrollToGroup === undefined || that.options.scrollToGroup) { + that.selectObjectInBottomTab(); + } }); }, diff --git a/src/js/plate-layout.js b/src/js/plate-layout.js index 87bf4ec..398d286 100755 --- a/src/js/plate-layout.js +++ b/src/js/plate-layout.js @@ -1,287 +1,331 @@ $.widget("DNA.plateLayOut", { - plateLayOutWidget: {}, - - options: { - value: 0 - }, - - allTiles: [], // All tiles containes all thise circles in the canvas - - addressToLoc: function (layoutAddress) { - var m = /^([A-Z]+)(\d+)$/.exec(layoutAddress.trim().toUpperCase()) - if (m) { - var row_v = m[1]; - var col = parseInt(m[2])-1; - var row; - for (var i = 0; i < row_v.length; i++) { - var c = row_v.charCodeAt(i) - 65; - if (i) { - row += 1; - row *= 26; - row += c ; + plateLayOutWidget: {}, + + options: { + value: 0 + }, + + allTiles: [], // All tiles containes all thise circles in the canvas + + addressToLoc: function (layoutAddress) { + var m = /^([A-Z]+)(\d+)$/.exec(layoutAddress.trim().toUpperCase()) + if (m) { + var row_v = m[1]; + var col = parseInt(m[2]) - 1; + var row; + for (var i = 0; i < row_v.length; i++) { + var c = row_v.charCodeAt(i) - 65; + if (i) { + row += 1; + row *= 26; + row += c; + } else { + row = c; + } + } + return { + r: row, + c: col + }; } else { - row = c; + throw layoutAddress + " not a proper layout address"; } - } - return { - r: row, - c: col - }; - } else { - throw layoutAddress + " not a proper layout address"; - } - }, + }, - locToIndex: function (loc, dimensions) { - if (!dimensions) { - dimensions = this.dimensions; - } - if (loc.r < 0) { - t - } - if (!(loc.r >= 0 && loc.r < dimensions.rows)) { - throw "Row index " + (loc.r + 1) + " invalid"; - } - if (!(loc.c >= 0 && loc.c < dimensions.cols)) { - throw "Column index " + (loc.c + 1) + " invalid"; - } - return loc.r*dimensions.cols + loc.c; - }, - - addressToIndex: function (layoutAddress, dimensions) { - var loc = this.addressToLoc(layoutAddress); - return this.locToIndex(loc, dimensions); - }, - - _rowKey: function (i) { - var c1 = i % 26; - var c2 = (i - c1) / 26; - var code = String.fromCharCode(65 + c1); - if (c2 > 0) { - code = String.fromCharCode(64 + c2) + code; - } - return code; - }, + locToIndex: function (loc, dimensions) { + if (!dimensions) { + dimensions = this.dimensions; + } + if (loc.r < 0) { + t + } + if (!(loc.r >= 0 && loc.r < dimensions.rows)) { + throw "Row index " + (loc.r + 1) + " invalid"; + } + if (!(loc.c >= 0 && loc.c < dimensions.cols)) { + throw "Column index " + (loc.c + 1) + " invalid"; + } + return loc.r * dimensions.cols + loc.c; + }, + + addressToIndex: function (layoutAddress, dimensions) { + var loc = this.addressToLoc(layoutAddress); + return this.locToIndex(loc, dimensions); + }, + + _rowKey: function (i) { + var c1 = i % 26; + var c2 = (i - c1) / 26; + var code = String.fromCharCode(65 + c1); + if (c2 > 0) { + code = String.fromCharCode(64 + c2) + code; + } + return code; + }, - indexToLoc: function (index, dimensions) { - if (!dimensions) { - dimensions = this.dimensions; - } + indexToLoc: function (index, dimensions) { + if (!dimensions) { + dimensions = this.dimensions; + } - if (index >= dimensions.rows * dimensions.cols) { - throw "Index too high: " + index.toString(10); - } - var loc = {}; - loc.c = index % dimensions.cols; - loc.r = (index - loc.c) / dimensions.cols; - - return loc; - }, - - locToAddress: function (loc) { - return this._rowKey(loc.r) + (loc.c + 1).toString(10); - }, - - indexToAddress: function (index, dimensions) { - var loc = this.indexToLoc(index, dimensions); - return this.locToAddress(loc); - }, - - getDimensions: function () { - return $.extend(true, {}, this.dimensions); - }, - - _create: function() { - var rows = parseInt(this.options.numRows || 8); - var cols = parseInt(this.options.numCols || 12); - this.dimensions = { - rows: rows, - cols: cols - }; - this.rowIndex = []; - for (var i = 0; i < rows; i++) { - this.rowIndex.push(this._rowKey(i)); - } + if (index >= dimensions.rows * dimensions.cols) { + throw "Index too high: " + index.toString(10); + } + var loc = {}; + loc.c = index % dimensions.cols; + loc.r = (index - loc.c) / dimensions.cols; + + return loc; + }, + + locToAddress: function (loc) { + return this._rowKey(loc.r) + (loc.c + 1).toString(10); + }, + + indexToAddress: function (index, dimensions) { + var loc = this.indexToLoc(index, dimensions); + return this.locToAddress(loc); + }, + + getDimensions: function () { + return $.extend(true, {}, this.dimensions); + }, + + _create: function () { + var rows = parseInt(this.options.numRows || 8); + var cols = parseInt(this.options.numCols || 12); + this.dimensions = { + rows: rows, + cols: cols + }; + this.rowIndex = []; + for (var i = 0; i < rows; i++) { + this.rowIndex.push(this._rowKey(i)); + } - this.target = (this.element[0].id) ? "#" + this.element[0].id : "." + this.element[0].className; + this.target = (this.element[0].id) ? "#" + this.element[0].id : "." + this.element[0].className; - // Import classes from other files.. Here we import it using extend and add it to this - // object. internally we add to widget.DNA.getPlates.prototype. - // Helpers are methods which return other methods and objects. - // add Objects to plateLayOutWidget and it will be added to this object. - // set read only well - if (this.options.readOnly){ - this.isReadOnly(true); - } + // Import classes from other files.. Here we import it using extend and add it to this + // object. internally we add to widget.DNA.getPlates.prototype. + // Helpers are methods which return other methods and objects. + // add Objects to plateLayOutWidget and it will be added to this object. + // set read only well + if (this.options.readOnly) { + this.isReadOnly(true); + } - for (var component in plateLayOutWidget) { - // Incase some properties has to initialize with data from options hash, - // we provide it sending this object. - $.extend(this, new plateLayOutWidget[component](this)); - } + for (var component in plateLayOutWidget) { + // Incase some properties has to initialize with data from options hash, + // we provide it sending this object. + $.extend(this, new plateLayOutWidget[component](this)); + } - this.imgSrc = this.options.imgSrc || "assets"; - - this._createInterface(); - - this._trigger("created", null, this); - - return this; - }, - - _init: function() { - // This is invoked when the user use the plugin after _create is called. - // The point is _create is invoked for the very first time and for all other - // times _init is used. - }, - - addData: function() { - alert("wow this is good"); - }, - - // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}} - getTextDerivative: function(wellsData) { - var textDerivative = {}; - var fieldMap = this.fieldMap; - for (var idx in wellsData){ - var textValWell = {}; - var textFieldIdWell = {}; - var curWellData = wellsData[idx]; - for (var fieldId in curWellData){ - if (fieldId in this.fieldMap){ - var field = this.fieldMap[fieldId]; - var textVal = field.parseText(curWellData[fieldId]); - textFieldIdWell[field.name] = textVal; - textValWell[fieldId] = textVal; - } else { - // do not convert if not a field (ex: layout_address) - textFieldIdWell[fieldId] = curWellData[fieldId]; - textValWell[fieldId] = curWellData[fieldId]; + this.imgSrc = this.options.imgSrc || "assets"; + + this._createInterface(); + + this._trigger("created", null, this); + + return this; + }, + + _init: function () { + // This is invoked when the user use the plugin after _create is called. + // The point is _create is invoked for the very first time and for all other + // times _init is used. + }, + + addData: function () { + alert("wow this is good"); + }, + + // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}} + getTextDerivative: function (wellsData) { + var textDerivative = {}; + var fieldMap = this.fieldMap; + for (var idx in wellsData) { + var textValWell = {}; + var textFieldIdWell = {}; + var curWellData = wellsData[idx]; + for (var fieldId in curWellData) { + if (fieldId in this.fieldMap) { + var field = this.fieldMap[fieldId]; + var textVal = field.parseText(curWellData[fieldId]); + textFieldIdWell[field.name] = textVal; + textValWell[fieldId] = textVal; + } else { + // do not convert if not a field (ex: layout_address) + textFieldIdWell[fieldId] = curWellData[fieldId]; + textValWell[fieldId] = curWellData[fieldId]; + } + } + textDerivative[idx] = { + textVal: textValWell, + textFieldVal: textFieldIdWell + }; } - } - textDerivative[idx] = { - textVal: textValWell, - textFieldVal: textFieldIdWell - }; - } - return textDerivative; - }, - - // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}} - getWellsDifferences: function(wellsData) { - return this.getDifferentWellsVals(wellsData); - }, - - setFieldsDisabled: function(flag){ - this.fieldList.forEach(function(field){ - field.disabled(flag); - }); - }, - - isReadOnly: function(flag){ - if (flag){ - this.readOnly = true; - } else { - this.readOnly = false; - } - this.readOnlyHandler(); - }, - - readOnlyHandler: function(){ - if (this.readOnly){ - this.overLayButtonContainer.css("display", "none"); - $('.multiple-field-manage-delete-button').css("display", "none"); - this.setFieldsDisabled(true); - } else { - this.overLayButtonContainer.css("display", "flex"); - $('.multiple-field-manage-delete-button').css("display", "none"); - if (!this.disableAddDeleteWell) { - this.setFieldsDisabled(false); - } - } - }, - - disableAddDeleteWell: null, - // column_with_default_val will be used to determine empty wells, format: {field_name: default_val} - isDisableAddDeleteWell: function(flag, column_with_default_val){ - if (flag){ - this.disableAddDeleteWell = true; - this.addressAllowToEdit = this.getWellSetAddressWithData(); - // configure undo redo action - this.actionPointer = 0; - this.undoRedoArray = []; - this.undoRedoArray.push(this.createObject()); - if (column_with_default_val) { - this.emptyWellWithDefaultVal = column_with_default_val; - } - } else { - this.disableAddDeleteWell = false; - this.setFieldsDisabled(false); - this.emptyWellWithDefaultVal = null; - } - this._fabricEvents(); - }, + return textDerivative; + }, - getSelectedObject: function() { - var selectedAddress = []; - for (var i = 0; i < this.allSelectedObjects.length; i++){ - selectedAddress.push(this.allSelectedObjects[i].address); - } - var selectedObjects = {}; - var derivative = this.engine.derivative; - for (var loc in derivative){ - var address = this.indexToAddress(loc); - if (selectedAddress.indexOf(address) >= 0) { - selectedObjects[address] = derivative[loc]; - } - } - return selectedObjects; - }, - - getSelectedIndex: function() { - return this.allSelectedObjects.map(function(selectedObj){ - return that.addressToIndex(selectedObj.address) - }); - }, - - getSelectedAddress: function() { - return this.allSelectedObjects.map(function(selectedObj){ - return selectedObj.address; - }); - }, - - setSelectedWell: function(addressList) { - var areas = []; - var minRow = 999; - var locMap = {}; - for (var id = 0; id < addressList.length; id++){ - var wellIdx = this.addressToIndex(addressList[id]); - var loc = this.indexToLoc(wellIdx); - areas.push({ - minCol: loc.c, - minRow: loc.r, - maxCol: loc.c, - maxRow: loc.r - }); - if (loc.r <= minRow) { - minRow = loc.r; - if (loc.r in locMap) { - locMap[loc.r].push(loc.c); + // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}} + getWellsDifferences: function (wellsData) { + return this.getDifferentWellsVals(wellsData); + }, + + setFieldsDisabled: function (flag) { + this.fieldList.forEach(function (field) { + field.disabled(flag); + }); + }, + + isReadOnly: function (flag) { + if (flag) { + this.readOnly = true; } else { - locMap[loc.r] = [loc.c]; + this.readOnly = false; } - } - } - var focalWell = { - row: minRow, - col: Math.min.apply(null, locMap[minRow]) - }; + this.readOnlyHandler(); + }, + + readOnlyHandler: function () { + if (this.readOnly) { + this.overLayButtonContainer.css("display", "none"); + $('.multiple-field-manage-delete-button').css("display", "none"); + this.setFieldsDisabled(true); + } else { + this.overLayButtonContainer.css("display", "flex"); + $('.multiple-field-manage-delete-button').css("display", "none"); + if (!this.disableAddDeleteWell) { + this.setFieldsDisabled(false); + } + } + }, + + disableAddDeleteWell: null, + // column_with_default_val will be used to determine empty wells, format: {field_name: default_val} + isDisableAddDeleteWell: function (flag, column_with_default_val) { + if (flag) { + this.disableAddDeleteWell = true; + this.addressAllowToEdit = this.getWellSetAddressWithData(); + // configure undo redo action + this.actionPointer = 0; + this.undoRedoArray = []; + this.undoRedoArray.push(this.createObject()); + if (column_with_default_val) { + this.emptyWellWithDefaultVal = column_with_default_val; + } + } else { + this.disableAddDeleteWell = false; + this.setFieldsDisabled(false); + this.emptyWellWithDefaultVal = null; + } + this._fabricEvents(); + }, - this.setSelection(areas, focalWell); - this.decideSelectedFields(); - this.mainFabricCanvas.renderAll(); - } + getSelectedObject: function () { + var selectedAddress = []; + for (var i = 0; i < this.allSelectedObjects.length; i++) { + selectedAddress.push(this.allSelectedObjects[i].address); + } + var selectedObjects = {}; + var derivative = this.engine.derivative; + for (var index in derivative) { + var address = this.indexToAddress(index); + if (selectedAddress.indexOf(address) >= 0) { + var well = JSON.parse(JSON.stringify(derivative[index])); + well.colorIndex = this.engine.colorMap.get(Number(index)); + selectedObjects[address] = well; + } + } + return selectedObjects; + }, + + selectObjectInBottomTab: function () { + var selectedObjects = this.getSelectedObject(); + var selectedObjectAddress; + for (var prop in selectedObjects) { + if (!selectedObjectAddress) { + selectedObjectAddress = prop; + } else { + return; // scroll to matching group only if a single well has been selected + } + } + if (selectedObjects[selectedObjectAddress]) { + var colorIndex = selectedObjects[selectedObjectAddress].colorIndex; + var trs = document.querySelectorAll('table.plate-setup-bottom-table tr'); + for (var i = 1; i < trs.length; i++) { // start at 1 to skip the table headers + var tds = trs[i].children; + var isSelected = tds[0].querySelector('button').innerHTML === colorIndex.toString(); + for (var j = 1; j < tds.length; j++) { + if (isSelected) { + tds[j].style.background = '#22cb94'; + } else { + tds[j].style.background = '#ffffff'; + } + } + if (isSelected) { + scrollTo(document.querySelector('.plate-setup-bottom-table-container'), tds[0].offsetTop, 300); + } + } + } + }, + + getSelectedIndex: function () { + return this.allSelectedObjects.map(function (selectedObj) { + return that.addressToIndex(selectedObj.address) + }); + }, + + getSelectedAddress: function () { + return this.allSelectedObjects.map(function (selectedObj) { + return selectedObj.address; + }); + }, + + setSelectedWell: function (addressList) { + var areas = []; + var minRow = 999; + var locMap = {}; + for (var id = 0; id < addressList.length; id++) { + var wellIdx = this.addressToIndex(addressList[id]); + var loc = this.indexToLoc(wellIdx); + areas.push({ + minCol: loc.c, + minRow: loc.r, + maxCol: loc.c, + maxRow: loc.r + }); + if (loc.r <= minRow) { + minRow = loc.r; + if (loc.r in locMap) { + locMap[loc.r].push(loc.c); + } else { + locMap[loc.r] = [loc.c]; + } + } + } + var focalWell = { + row: minRow, + col: Math.min.apply(null, locMap[minRow]) + }; + + this.setSelection(areas, focalWell); + this.decideSelectedFields(); + this.mainFabricCanvas.renderAll(); + } -}); \ No newline at end of file +}); + +// https://stackoverflow.com/questions/17733076/smooth-scroll-anchor-links-without-jquery +function scrollTo(element, to, duration) { + if (duration <= 0) return; + var difference = to - element.scrollTop; + var perTick = difference / duration * 10; + setTimeout(function () { + element.scrollTop = element.scrollTop + perTick; + if (element.scrollTop === to) return; + scrollTo(element, to, duration - 10); + }, 10); +} \ No newline at end of file From a1ddba00b0d60809a361fca7939c26b4f82a7511 Mon Sep 17 00:00:00 2001 From: Jeremy Gore <jeremy.gore@tessella.com> Date: Thu, 14 Mar 2019 12:35:16 -0400 Subject: [PATCH 05/10] Remove obsolete imgSrc option --- README.md | 1 - dist/css/plate-map.css | 491 ---- dist/css/plate-map.min.css | 2 - dist/css/plate-map.min.css.map | 1 - dist/js/plate-map.js | 4360 -------------------------------- dist/js/plate-map.min.js | 2 - dist/js/plate-map.min.js.map | 1 - dist/package.json | 49 - src/js/plate-layout.js | 2 - 9 files changed, 4909 deletions(-) delete mode 100644 dist/css/plate-map.css delete mode 100644 dist/css/plate-map.min.css delete mode 100644 dist/css/plate-map.min.css.map delete mode 100755 dist/js/plate-map.js delete mode 100755 dist/js/plate-map.min.js delete mode 100644 dist/js/plate-map.min.js.map delete mode 100644 dist/package.json diff --git a/README.md b/README.md index c3cba77..6b643d1 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,6 @@ the Github repository. $("#my-plate-layout").plateLayOut({ numRows: 8, numCols: 12, - imgSrc: "css", readOnly: false, // optional attributes: attributes, updateWells: function(event, data) { diff --git a/dist/css/plate-map.css b/dist/css/plate-map.css deleted file mode 100644 index f44a69c..0000000 --- a/dist/css/plate-map.css +++ /dev/null @@ -1,491 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Roboto); - -.plate-setup-container { - width: 1024px; - height: 768px; - position: relative; - float: left; -} - -.plate-setup-wrapper { - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - flex-direction: column; - background-color: #f5f5f5; -} - -.plate-setup-top-section { - height: 540px; - top: 0; - left: 0; - right: 0; - position: absolute; -} - -.plate-setup-top-left { - width: 674px; - top: 0; - bottom: 0; - position: absolute; -} - -.plate-setup-top-right { - left: 674px; - top: 0; - bottom: 0; - right: 0; - position: absolute; -} - -.plate-setup-overlay-container { - height: 32px; - top: 10px; - left: 16px; - right: 16px; - position: inherit; - background-color: #464646; - border-radius: 2px; - display: flex; - justify-content: space-between; - align-items: baseline; - vertical-align: middle; -} - -.plate-setup-overlay-radio-container { - width: 32px; - height: 32px; -} - -.plate-setup-overlay-text-container { - color: white; - font-size: 12px; - line-height: 30px; - height: 32px; - font-family: "Roboto", Arial, sans-serif; - margin: 2px 8px; - flex: 1 1 auto; -} - -.plate-setup-overlay-button-container, .plate-setup-overlay-bottom-button-container { - flex: 0 0 auto; - display: flex; - flex: 1 1 0; -} - -.plate-setup-button { - height: 23px; - font-family: "Roboto", Arial, sans-serif; - font-size: 12px; - border: none; - background-color: white; - border-radius: 2px; - margin-right: 4px; - flex: 1 0 0; - white-space: nowrap; -} - -.plate-setup-clicked-button { - height: 23px; - font-family: "Roboto", Arial, sans-serif; - font-size: 12px; - border: none; - background-color: aquamarine; - border-radius: 2px; - margin-right: 4px; - flex: 1 0 0; - white-space: nowrap; -} - - -.plate-setup-canvas-container { - top: 52px; - left: 16px; - right: 16px; - bottom: 10px; - position: absolute; -} - -.plate-setup-tab-container { - position: absolute; - top:10px; - left:10px; - bottom: 10px; - right: 10px; - background-color: white; - border: solid 1px #e1e1e1; -} - -.plate-setup-tab-head { - left: 0; - right: 0; - height: 23px; - border-bottom: solid 1px #e1e1e1; - background-color: #f5f5f5; - display: flex; -} - -.plate-setup-tab { - height: 23px; - background-color: #ebebeb; - border-right: solid 1px #e1e1e1; - cursor: pointer; - font-family: "Roboto", Arial, sans-serif; - font-size: 10px; - text-align: center; - padding: 5px; - box-sizing: border-box; - flex: 1 1 auto; - white-space: nowrap; - overflow: hidden; -} - -.plate-setup-tab:last-child { - border-right: none; -} - -.plate-setup-tab-selected { - height: 24px; - background-color: white; - color: #00506e; - flex-shrink: 0; -} - -.plate-setup-tab-data-container { - left: 0; - right: 0; - height: 442px; - border-bottom: solid 1px #e1e1e1; - position: absolute; - font-family: "Roboto", Arial, sans-serif; -} - -.plate-setup-data-div { - top: 0; - left: 0; - bottom: 0; - right: 0; - position: absolute; - background-color: white; - overflow: auto; -} - -.plate-setup-well-attr-container { - top: 472px; - left: 0; - right: 0; - height: 20px; - box-sizing: border-box; - padding: 0px 16px; - color: #00506e; - text-align: center; - position: absolute; - font-size: 10px; - font-family: "Roboto", Arial, sans-serif; -} - -.plate-setup-preset-container { - top: 490px; - left: 0; - right: 0; - height: 22px; - position: absolute; - box-sizing: border-box; - padding: 0px 16px; - text-align: center; - display: flex; - justify-content: center; -} - -.plate-setup-prest-tab { - display: inline-block; - flex-basis: 50px; - padding: 0 5px; - margin: 0 1px; - height: 20px; - background-color: white; - border: solid 1px #e1e1e1; - border-radius: 2px; - cursor: pointer; - font-family: "Roboto", Arial, sans-serif; - font-size: 10px; - text-align: center; -} - -.plate-setup-prest-tab-selected { - display: inline-block; - flex-basis: 50px; - padding: 0 5px; - margin: 0 1px; - height: 20px; - background-color: #e1e1e1; - border: solid 1px #e1e1e1; - border-radius: 2px; - cursor: pointer; - font-family: "Roboto", Arial, sans-serif; - font-size: 11px; - text-align: center; - color: #00506e; -} - -.plate-setup-prest-tab-div { - padding-top: 3px; -} - -.plate-setup-tab-default-field { - display: flex; - padding: 10px 16px 0 16px; -} - -.plate-setup-tab-field-left-side { - width: 32px; - padding-top: 16px; -} - -.plate-setup-tab-field-right-side { - flex: 1; -} - -.plate-setup-tab-name { - font-family: "Roboto", Arial, sans-serif; - font-size: 12px; - display: inline-block; - line-height: 16px; -} - -.plate-setup-tab-name-singleSelect { - font-family: "Roboto", Arial, sans-serif; - font-size: 12px; - margin-top: 5px; -} - - -.plate-setup-tab-name-missing { - height: 20px; - font-family: "Roboto", Arial, sans-serif; - font-size: 12px; - background: red; -} - - -.plate-setup-tab-field-container, .plate-setup-tab-field-container-singleSelect { - width: 100%; - display: flex; -} - -.plate-setup-tab-input, .plate-setup-tab-select-field, .plate-setup-tab-multiplex-single-select-field { - height: 28px; - flex: 1 1 auto; - width: 30px; - margin: auto; -} - -.plate-setup-tab-multiselect-field { - min-height: 28px; - flex: 1 1 auto; - width: 30px; -} - -.plate-setup-tab-label-select-field, .plate-setup-tab-unit { - width: 130px; - overflow: hidden; - text-overflow: ellipsis; - height: 28px; - box-sizing: border-box; - padding-left: 5px; -} - -.plate-setup-tab-unit { - font-family: "Roboto", Arial, sans-serif; - line-height: 26px; - color: #444; - white-space: nowrap; -} - -.plate-setup-tab-check-box { - cursor: pointer; - border: 1px solid gray; - display: inline-block; - height: 16px; - width: 16px; - text-align: center; - line-height: 16px; -} - -.plate-setup-bottom-control-container { - top: 0; - left: 0; - right: 0; - height: 32px; - background-color: #464646; - position: absolute; - display: flex; - justify-content:space-between; - align-items: baseline; - vertical-align: middle; -} - -.plate-setup-bottom-container { - top: 540px; - left: 0; - right: 0; - bottom: 0; - position: absolute; - background-color: #e1e1e1; -} - -.plate-setup-bottom-table-container { - top: 32px; - left: 0; - bottom: 0; - right: 0; - position: absolute; - overflow: auto; -} - - -.plate-setup-bottom-table { - font-family: "Roboto", Arial, sans-serif; - font-size: 14px; - border-collapse: collapse; - width: 100%; -} - -.plate-setup-bottom-table th { - border: solid #c2c2c2 1px; - padding: 5px 10px; - font-weight: bold; - font-size: 12px; - text-align: left; -} - -.plate-setup-bottom-table td { - border: solid #c2c2c2 1px; - padding: 5px 10px; - background-color: white; -} - -.plate-setup-color-text { - font-size: 14px; - border: none; - border-radius: 2px; - padding: 3px 15px; - background-color: WHITE; - margin-right: 4px; -} - -.plate-setup-bottom-id { - width: 40px; - text-align: center; - background-image: linear-gradient(to right, rgba(255,255,255,0.3), transparent) -} - -input.invalid { - background-color: pink; -} - -.plate-setup-remove-all-button-container { - text-align: left; -} - -.plate-setup-remove-all-button{ - width: 100%; - font-family: "Roboto", Arial, sans-serif; - font-size: 12px; - text-overflow: ellipsis; - text-align: left; - white-space: nowrap; - border: 1px solid #aaa; - border-top: none; - color: #444; - background-color: #fff; - background-image: linear-gradient(to top, #eee 0%, #fff 50%); -} -/* Modal Content */ - -.modal { - display: none; /* Hidden by default */ - position: fixed; /* Stay in place */ - z-index: 2000; /* Sit on top */ - padding-top: 100px; /* Location of the box */ - left: 0; - top: 0; - width: 100%; /* Full width */ - height: 100%; /* Full height */ - overflow: auto; /* Enable scroll if needed */ - background-color: rgb(0,0,0); /* Fallback color */ - background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ -} - -.modal-content { - font-family: 'Roboto', sans-serif; - font-size: 14px; - background-color: #fefefe; - margin: auto; - padding: 20px; - border: 1px solid #888; -} - -.delete-dialog .modal-content { - width: 550px; -} - -.modal-content > * { - width: 100%; -} - -.dialog-buttons { - margin-top: 10px; - display: inline-block; - text-align: right; -} - -.dialog-buttons button { - margin-left: 4px; -} - -.plate-popout-table { - border-collapse: collapse; - width: 100%; - border: 1px solid black; - padding: 5px; -} - -.plate-popout-th { - text-align: left; - background-color: white; - color: black; - font-size: 12px; - border: 1px solid black; - padding: 5px; -} - -.plate-popout-tr:hover { - background-color: #f5f5f5; - border: 1px solid black; - padding: 5px; -} - -.plate-popout-td { - text-align: left; - font-size: 11px; - border: 1px solid black; - padding: 5px; -} - -.plate-field-warning-image{ - vertical-align: baseline; - margin: 0px 0 0px; -} - -.pop-out-text { - position: fixed; - display: none; - background: white; - border: 1px solid; - float: left; - margin-top: -44px; - z-Index: 99999 !important; -} diff --git a/dist/css/plate-map.min.css b/dist/css/plate-map.min.css deleted file mode 100644 index d7ff6e2..0000000 --- a/dist/css/plate-map.min.css +++ /dev/null @@ -1,2 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Roboto);.plate-setup-container{width:1024px;height:768px;position:relative;float:left}.plate-setup-wrapper{position:absolute;top:0;left:0;bottom:0;right:0;flex-direction:column;background-color:#f5f5f5}.plate-setup-top-section{height:540px;top:0;left:0;right:0;position:absolute}.plate-setup-top-left{width:674px;top:0;bottom:0;position:absolute}.plate-setup-top-right{left:674px;top:0;bottom:0;right:0;position:absolute}.plate-setup-overlay-container{height:32px;top:10px;left:16px;right:16px;position:inherit;background-color:#464646;border-radius:2px;display:flex;justify-content:space-between;align-items:baseline;vertical-align:middle}.plate-setup-overlay-radio-container{width:32px;height:32px}.plate-setup-overlay-text-container{color:#fff;font-size:12px;line-height:30px;height:32px;font-family:Roboto,Arial,sans-serif;margin:2px 8px;flex:1 1 auto}.plate-setup-overlay-bottom-button-container,.plate-setup-overlay-button-container{flex:0 0 auto;display:flex;flex:1 1 0}.plate-setup-button{height:23px;font-family:Roboto,Arial,sans-serif;font-size:12px;border:none;background-color:#fff;border-radius:2px;margin-right:4px;flex:1 0 0;white-space:nowrap}.plate-setup-clicked-button{height:23px;font-family:Roboto,Arial,sans-serif;font-size:12px;border:none;background-color:#7fffd4;border-radius:2px;margin-right:4px;flex:1 0 0;white-space:nowrap}.plate-setup-canvas-container{top:52px;left:16px;right:16px;bottom:10px;position:absolute}.plate-setup-tab-container{position:absolute;top:10px;left:10px;bottom:10px;right:10px;background-color:#fff;border:solid 1px #e1e1e1}.plate-setup-tab-head{left:0;right:0;height:23px;border-bottom:solid 1px #e1e1e1;background-color:#f5f5f5;display:flex}.plate-setup-tab{height:23px;background-color:#ebebeb;border-right:solid 1px #e1e1e1;cursor:pointer;font-family:Roboto,Arial,sans-serif;font-size:10px;text-align:center;padding:5px;box-sizing:border-box;flex:1 1 auto;white-space:nowrap;overflow:hidden}.plate-setup-tab:last-child{border-right:none}.plate-setup-tab-selected{height:24px;background-color:#fff;color:#00506e;flex-shrink:0}.plate-setup-tab-data-container{left:0;right:0;height:442px;border-bottom:solid 1px #e1e1e1;position:absolute;font-family:Roboto,Arial,sans-serif}.plate-setup-data-div{top:0;left:0;bottom:0;right:0;position:absolute;background-color:#fff;overflow:auto}.plate-setup-well-attr-container{top:472px;left:0;right:0;height:20px;box-sizing:border-box;padding:0 16px;color:#00506e;text-align:center;position:absolute;font-size:10px;font-family:Roboto,Arial,sans-serif}.plate-setup-preset-container{top:490px;left:0;right:0;height:22px;position:absolute;box-sizing:border-box;padding:0 16px;text-align:center;display:flex;justify-content:center}.plate-setup-prest-tab{display:inline-block;flex-basis:50px;padding:0 5px;margin:0 1px;height:20px;background-color:#fff;border:solid 1px #e1e1e1;border-radius:2px;cursor:pointer;font-family:Roboto,Arial,sans-serif;font-size:10px;text-align:center}.plate-setup-prest-tab-selected{display:inline-block;flex-basis:50px;padding:0 5px;margin:0 1px;height:20px;background-color:#e1e1e1;border:solid 1px #e1e1e1;border-radius:2px;cursor:pointer;font-family:Roboto,Arial,sans-serif;font-size:11px;text-align:center;color:#00506e}.plate-setup-prest-tab-div{padding-top:3px}.plate-setup-tab-default-field{display:flex;padding:10px 16px 0 16px}.plate-setup-tab-field-left-side{width:32px;padding-top:16px}.plate-setup-tab-field-right-side{flex:1}.plate-setup-tab-name{font-family:Roboto,Arial,sans-serif;font-size:12px;display:inline-block;line-height:16px}.plate-setup-tab-name-singleSelect{font-family:Roboto,Arial,sans-serif;font-size:12px;margin-top:5px}.plate-setup-tab-name-missing{height:20px;font-family:Roboto,Arial,sans-serif;font-size:12px;background:red}.plate-setup-tab-field-container,.plate-setup-tab-field-container-singleSelect{width:100%;display:flex}.plate-setup-tab-input,.plate-setup-tab-multiplex-single-select-field,.plate-setup-tab-select-field{height:28px;flex:1 1 auto;width:30px;margin:auto}.plate-setup-tab-multiselect-field{min-height:28px;flex:1 1 auto;width:30px}.plate-setup-tab-label-select-field,.plate-setup-tab-unit{width:130px;overflow:hidden;text-overflow:ellipsis;height:28px;box-sizing:border-box;padding-left:5px}.plate-setup-tab-unit{font-family:Roboto,Arial,sans-serif;line-height:26px;color:#444;white-space:nowrap}.plate-setup-tab-check-box{cursor:pointer;border:1px solid gray;display:inline-block;height:16px;width:16px;text-align:center;line-height:16px}.plate-setup-bottom-control-container{top:0;left:0;right:0;height:32px;background-color:#464646;position:absolute;display:flex;justify-content:space-between;align-items:baseline;vertical-align:middle}.plate-setup-bottom-container{top:540px;left:0;right:0;bottom:0;position:absolute;background-color:#e1e1e1}.plate-setup-bottom-table-container{top:32px;left:0;bottom:0;right:0;position:absolute;overflow:auto}.plate-setup-bottom-table{font-family:Roboto,Arial,sans-serif;font-size:14px;border-collapse:collapse;width:100%}.plate-setup-bottom-table th{border:solid #c2c2c2 1px;padding:5px 10px;font-weight:700;font-size:12px;text-align:left}.plate-setup-bottom-table td{border:solid #c2c2c2 1px;padding:5px 10px;background-color:#fff}.plate-setup-color-text{font-size:14px;border:none;border-radius:2px;padding:3px 15px;background-color:#fff;margin-right:4px}.plate-setup-bottom-id{width:40px;text-align:center;background-image:linear-gradient(to right,rgba(255,255,255,.3),transparent)}input.invalid{background-color:pink}.plate-setup-remove-all-button-container{text-align:left}.plate-setup-remove-all-button{width:100%;font-family:Roboto,Arial,sans-serif;font-size:12px;text-overflow:ellipsis;text-align:left;white-space:nowrap;border:1px solid #aaa;border-top:none;color:#444;background-color:#fff;background-image:linear-gradient(to top,#eee 0,#fff 50%)}.modal{display:none;position:fixed;z-index:2000;padding-top:100px;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:#000;background-color:rgba(0,0,0,.4)}.modal-content{font-family:Roboto,sans-serif;font-size:14px;background-color:#fefefe;margin:auto;padding:20px;border:1px solid #888}.delete-dialog .modal-content{width:550px}.modal-content>*{width:100%}.dialog-buttons{margin-top:10px;display:inline-block;text-align:right}.dialog-buttons button{margin-left:4px}.plate-popout-table{border-collapse:collapse;width:100%;border:1px solid #000;padding:5px}.plate-popout-th{text-align:left;background-color:#fff;color:#000;font-size:12px;border:1px solid #000;padding:5px}.plate-popout-tr:hover{background-color:#f5f5f5;border:1px solid #000;padding:5px}.plate-popout-td{text-align:left;font-size:11px;border:1px solid #000;padding:5px}.plate-field-warning-image{vertical-align:baseline;margin:0 0 0}.pop-out-text{position:fixed;display:none;background:#fff;border:1px solid;float:left;margin-top:-44px;z-Index:99999!important} -/*# sourceMappingURL=plate-map.min.css.map */ \ No newline at end of file diff --git a/dist/css/plate-map.min.css.map b/dist/css/plate-map.min.css.map deleted file mode 100644 index 1d3e613..0000000 --- a/dist/css/plate-map.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["plate-layout.css"],"names":[],"mappings":"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","file":"plate-map.min.css","sourcesContent":["@import url(http://fonts.googleapis.com/css?family=Roboto);\n\n.plate-setup-container {\n width: 1024px;\n height: 768px;\n position: relative;\n float: left;\n}\n\n.plate-setup-wrapper {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n flex-direction: column;\n background-color: #f5f5f5;\n}\n\n.plate-setup-top-section {\n height: 540px;\n top: 0;\n left: 0;\n right: 0;\n position: absolute;\n}\n\n.plate-setup-top-left {\n width: 674px;\n top: 0;\n bottom: 0;\n position: absolute;\n}\n\n.plate-setup-top-right {\n left: 674px;\n top: 0;\n bottom: 0;\n right: 0;\n position: absolute;\n}\n\n.plate-setup-overlay-container {\n height: 32px;\n top: 10px;\n left: 16px;\n right: 16px;\n position: inherit;\n background-color: #464646;\n border-radius: 2px;\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n vertical-align: middle;\n}\n\n.plate-setup-overlay-radio-container {\n width: 32px;\n height: 32px;\n}\n\n.plate-setup-overlay-text-container {\n color: white;\n font-size: 12px;\n line-height: 30px;\n height: 32px;\n font-family: \"Roboto\", Arial, sans-serif;\n margin: 2px 8px;\n flex: 1 1 auto;\n}\n\n.plate-setup-overlay-button-container, .plate-setup-overlay-bottom-button-container {\n flex: 0 0 auto;\n display: flex;\n flex: 1 1 0;\n}\n\n.plate-setup-button {\n height: 23px;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 12px;\n border: none;\n background-color: white;\n border-radius: 2px;\n margin-right: 4px;\n flex: 1 0 0;\n white-space: nowrap;\n}\n\n.plate-setup-clicked-button {\n height: 23px;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 12px;\n border: none;\n background-color: aquamarine;\n border-radius: 2px;\n margin-right: 4px;\n flex: 1 0 0;\n white-space: nowrap;\n}\n\n\n.plate-setup-canvas-container {\n top: 52px;\n left: 16px;\n right: 16px;\n bottom: 10px;\n position: absolute;\n}\n\n.plate-setup-tab-container {\n position: absolute;\n top:10px;\n left:10px;\n bottom: 10px;\n right: 10px;\n background-color: white;\n border: solid 1px #e1e1e1;\n}\n\n.plate-setup-tab-head {\n left: 0;\n right: 0;\n height: 23px;\n border-bottom: solid 1px #e1e1e1;\n background-color: #f5f5f5;\n display: flex;\n}\n\n.plate-setup-tab {\n height: 23px;\n background-color: #ebebeb;\n border-right: solid 1px #e1e1e1;\n cursor: pointer;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 10px;\n text-align: center;\n padding: 5px;\n box-sizing: border-box;\n flex: 1 1 auto;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.plate-setup-tab:last-child {\n border-right: none;\n}\n\n.plate-setup-tab-selected {\n height: 24px;\n background-color: white;\n color: #00506e;\n flex-shrink: 0;\n}\n\n.plate-setup-tab-data-container {\n left: 0;\n right: 0;\n height: 442px;\n border-bottom: solid 1px #e1e1e1;\n position: absolute;\n font-family: \"Roboto\", Arial, sans-serif;\n}\n\n.plate-setup-data-div {\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n position: absolute;\n background-color: white;\n overflow: auto;\n}\n\n.plate-setup-well-attr-container {\n top: 472px;\n left: 0;\n right: 0;\n height: 20px;\n box-sizing: border-box;\n padding: 0px 16px;\n color: #00506e;\n text-align: center;\n position: absolute;\n font-size: 10px;\n font-family: \"Roboto\", Arial, sans-serif;\n}\n\n.plate-setup-preset-container {\n top: 490px;\n left: 0;\n right: 0;\n height: 22px;\n position: absolute;\n box-sizing: border-box;\n padding: 0px 16px;\n text-align: center;\n display: flex;\n justify-content: center;\n}\n\n.plate-setup-prest-tab {\n display: inline-block;\n flex-basis: 50px;\n padding: 0 5px;\n margin: 0 1px;\n height: 20px;\n background-color: white;\n border: solid 1px #e1e1e1;\n border-radius: 2px;\n cursor: pointer;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 10px;\n text-align: center;\n}\n\n.plate-setup-prest-tab-selected {\n display: inline-block;\n flex-basis: 50px;\n padding: 0 5px;\n margin: 0 1px;\n height: 20px;\n background-color: #e1e1e1;\n border: solid 1px #e1e1e1;\n border-radius: 2px;\n cursor: pointer;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 11px;\n text-align: center;\n color: #00506e;\n}\n\n.plate-setup-prest-tab-div {\n padding-top: 3px;\n}\n\n.plate-setup-tab-default-field {\n display: flex;\n padding: 10px 16px 0 16px;\n}\n\n.plate-setup-tab-field-left-side {\n width: 32px;\n padding-top: 16px;\n}\n\n.plate-setup-tab-field-right-side {\n flex: 1;\n}\n\n.plate-setup-tab-name {\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 12px;\n display: inline-block;\n line-height: 16px;\n}\n\n.plate-setup-tab-name-singleSelect {\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 12px;\n margin-top: 5px;\n}\n\n\n.plate-setup-tab-name-missing {\n height: 20px;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 12px;\n background: red;\n}\n\n\n.plate-setup-tab-field-container, .plate-setup-tab-field-container-singleSelect {\n width: 100%;\n display: flex;\n}\n\n.plate-setup-tab-input, .plate-setup-tab-select-field, .plate-setup-tab-multiplex-single-select-field {\n height: 28px;\n flex: 1 1 auto;\n width: 30px;\n margin: auto;\n}\n\n.plate-setup-tab-multiselect-field {\n min-height: 28px;\n flex: 1 1 auto;\n width: 30px;\n}\n\n.plate-setup-tab-label-select-field, .plate-setup-tab-unit {\n width: 130px;\n overflow: hidden;\n text-overflow: ellipsis;\n height: 28px;\n box-sizing: border-box;\n padding-left: 5px;\n}\n\n.plate-setup-tab-unit {\n font-family: \"Roboto\", Arial, sans-serif;\n line-height: 26px;\n color: #444;\n white-space: nowrap;\n}\n\n.plate-setup-tab-check-box {\n cursor: pointer;\n border: 1px solid gray;\n display: inline-block;\n height: 16px;\n width: 16px;\n text-align: center;\n line-height: 16px;\n}\n\n.plate-setup-bottom-control-container {\n top: 0;\n left: 0;\n right: 0;\n height: 32px;\n background-color: #464646;\n position: absolute;\n display: flex;\n justify-content:space-between;\n align-items: baseline;\n vertical-align: middle;\n}\n\n.plate-setup-bottom-container {\n top: 540px;\n left: 0;\n right: 0;\n bottom: 0;\n position: absolute;\n background-color: #e1e1e1;\n}\n\n.plate-setup-bottom-table-container {\n top: 32px;\n left: 0;\n bottom: 0;\n right: 0;\n position: absolute;\n overflow: auto;\n}\n\n\n.plate-setup-bottom-table {\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 14px;\n border-collapse: collapse;\n width: 100%;\n}\n\n.plate-setup-bottom-table th {\n border: solid #c2c2c2 1px;\n padding: 5px 10px;\n font-weight: bold;\n font-size: 12px;\n text-align: left;\n}\n\n.plate-setup-bottom-table td {\n border: solid #c2c2c2 1px;\n padding: 5px 10px;\n background-color: white;\n}\n\n.plate-setup-color-text {\n font-size: 14px;\n border: none;\n border-radius: 2px;\n padding: 3px 15px;\n background-color: WHITE;\n margin-right: 4px;\n}\n\n.plate-setup-bottom-id {\n width: 40px;\n text-align: center;\n background-image: linear-gradient(to right, rgba(255,255,255,0.3), transparent)\n}\n\ninput.invalid {\n background-color: pink;\n}\n\n.plate-setup-remove-all-button-container {\n text-align: left;\n}\n\n.plate-setup-remove-all-button{\n width: 100%;\n font-family: \"Roboto\", Arial, sans-serif;\n font-size: 12px;\n text-overflow: ellipsis;\n text-align: left;\n white-space: nowrap;\n border: 1px solid #aaa;\n border-top: none;\n color: #444;\n background-color: #fff;\n background-image: linear-gradient(to top, #eee 0%, #fff 50%);\n}\n/* Modal Content */\n\n.modal {\n display: none; /* Hidden by default */\n position: fixed; /* Stay in place */\n z-index: 2000; /* Sit on top */\n padding-top: 100px; /* Location of the box */\n left: 0;\n top: 0;\n width: 100%; /* Full width */\n height: 100%; /* Full height */\n overflow: auto; /* Enable scroll if needed */\n background-color: rgb(0,0,0); /* Fallback color */\n background-color: rgba(0,0,0,0.4); /* Black w/ opacity */\n}\n\n.modal-content {\n font-family: 'Roboto', sans-serif;\n font-size: 14px;\n background-color: #fefefe;\n margin: auto;\n padding: 20px;\n border: 1px solid #888;\n}\n\n.delete-dialog .modal-content {\n width: 550px;\n}\n\n.modal-content > * {\n width: 100%;\n}\n\n.dialog-buttons {\n margin-top: 10px;\n display: inline-block;\n text-align: right;\n}\n\n.dialog-buttons button {\n margin-left: 4px;\n}\n\n.plate-popout-table {\n border-collapse: collapse;\n width: 100%;\n border: 1px solid black;\n padding: 5px;\n}\n\n.plate-popout-th {\n text-align: left;\n background-color: white;\n color: black;\n font-size: 12px;\n border: 1px solid black;\n padding: 5px;\n}\n\n.plate-popout-tr:hover {\n background-color: #f5f5f5;\n border: 1px solid black;\n padding: 5px;\n}\n\n.plate-popout-td {\n text-align: left;\n font-size: 11px;\n border: 1px solid black;\n padding: 5px;\n}\n\n.plate-field-warning-image{\n vertical-align: baseline;\n margin: 0px 0 0px;\n}\n\n.pop-out-text {\n position: fixed;\n display: none;\n background: white;\n border: 1px solid;\n float: left;\n margin-top: -44px;\n z-Index: 99999 !important;\n}\n"]} \ No newline at end of file diff --git a/dist/js/plate-map.js b/dist/js/plate-map.js deleted file mode 100755 index 8ab5e1c..0000000 --- a/dist/js/plate-map.js +++ /dev/null @@ -1,4360 +0,0 @@ -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.addDataOnChange = function() { - // This object is invoked when something in the tab fields change - return { - - _addAllData: function(data) { - // Method to add data when something changes in the tabs. Its going to be tricky , just starting. - if (this.allSelectedObjects) { - var noOfSelectedObjects = this.allSelectedObjects.length; - var wells = []; - for (var objectIndex = 0; objectIndex < noOfSelectedObjects; objectIndex++) { - var tile = this.allSelectedObjects[objectIndex]; - var well; - if (tile.index in this.engine.derivative) { - well = this.engine.derivative[tile.index]; - } else { - well = $.extend(true, {}, this.defaultWell); - this.engine.derivative[tile.index] = well; - } - var processedData = this.processWellData(data, well, noOfSelectedObjects, wells); - wells = processedData.wells; - well = processedData.well; - var empty = this.engine.wellEmpty(well); - if (empty) { - if (this.emptyWellWithDefaultVal && this.disableAddDeleteWell) { - var wellCopy = JSON.parse(JSON.stringify(well)); - var defaultValue = this.emptyWellWithDefaultVal; - for (var key in defaultValue){ - if (key in wellCopy){ - wellCopy[key] = defaultValue[key]; - this._applyFieldData(key, defaultValue[key]); - } - } - this.engine.derivative[tile.index] = wellCopy; - } else { - delete this.engine.derivative[tile.index]; - } - } - } - } - // update multiplex remove all field - this._getAllMultipleVal(wells); - this.applyFieldWarning(wells); - // create well when default field is sent for the cases when user delete all fields during disabledNewDeleteWell mode - this._colorMixer(); - this.derivativeChange(); - }, - - processWellData: function(newData, curWell, noOfSelectedObjects, wellList) { - - if (!wellList){ - wellList = []; - } - for (var id in newData) { - var v; - if (newData[id] !== undefined && newData[id] !== null ) { - if (newData[id].multi){ - var curData = newData[id]; - var preData = curWell[id]; - var newDt = this._getMultiData(preData, curData, id, noOfSelectedObjects); - // need to replace newData - v = JSON.parse(JSON.stringify(newDt)); - } else { - v = JSON.parse(JSON.stringify(newData[id])); - } - } else { - v = JSON.parse(JSON.stringify(newData[id])); - } - curWell[id] = v; - wellList.push(curWell); - } - - return { - well: curWell, - wells: wellList - } - }, - - _getMultiData: function(preData, curData, fieldId, noOfSelectedObjects) { - var addNew = curData.added; - var removed = curData.removed; - if (addNew) { - if (preData){ - if (addNew.value) { - var add = true; - for (var listIdx in preData) { - var multiplexData = preData[listIdx]; - // for cases when the add new data exist in well - if (multiplexData[fieldId].toString() === addNew.id.toString()) { - add = false; - // update subfield value - preData = preData.map(function(val) { - if (val[fieldId].toString() === addNew.id.toString()) { - for (var subFieldId in val) { - // over write previous data if only one well is selected - if (subFieldId in addNew.value && subFieldId !== fieldId){ - if (noOfSelectedObjects === 1) { - val[subFieldId] = addNew.value[subFieldId]; - } else if (addNew.value[subFieldId]) { - val[subFieldId] = addNew.value[subFieldId]; - } - } - } - } - return val; - }) - } - } - if (add) { - preData.push(addNew.value); - } - } else if (preData.indexOf(addNew) < 0) { - preData.push(addNew); - } - } else { - preData = []; - if (addNew.value) { - preData.push(addNew.value); - } else if (addNew){ - preData.push(addNew); - } - } - } - - var removeListIndex = function(preData, removeIndex) { - var newPreData = []; - for (var idx in preData) { - if (parseInt(idx) !== parseInt(removeIndex)){ - newPreData.push(preData[idx]); - } - } - return newPreData; - }; - - if (removed) { - var removeIndex; - // for multiplex field - if (removed.value) { - for (var listIdx in preData) { - var multiplexData = preData[listIdx]; - if (multiplexData[fieldId].toString() === removed.id.toString()) { - removeIndex = listIdx; - } - } - // remove nested element - preData = removeListIndex(preData, removeIndex); - } else { - if (preData){ - removeIndex = preData.indexOf(removed); - if (removeIndex >= 0) { - preData = removeListIndex(preData, removeIndex); - } - } - } - } - if (preData && (preData.length == 0)) { - preData = null; - } - return preData - }, - - _colorMixer: function() { - if (!this.undoRedoActive) { - var data = this.createObject(); - this.addToUndoRedo(data); - } - this.engine.searchAndStack(); - this.engine.applyColors(); - this.mainFabricCanvas.renderAll(); - }, - - derivativeChange: function(){ - this._trigger("updateWells", null, this.createObject()); - }, - - createObject: function() { - var derivative = $.extend(true, {}, this.engine.derivative); - var checkboxes = this.globalSelectedAttributes.slice(); - var selectedAreas = this.selectedAreas.slice(); - var focalWell = this.focalWell; - - return { - "derivative": derivative, - "checkboxes": checkboxes, - "selectedAreas": selectedAreas, - "focalWell": focalWell, - "requiredField": this.requiredField - }; - } - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.addDataToFields = function() { - - return { - - _addDataToTabFields: function(values) { - // Configure how data is added to tab fields - for (var id in values) { - this._applyFieldData(id, values[id]); - } - }, - - _applyFieldData: function(id, v) { - this.fieldMap[id].setValue(v); - } - } - } -})(jQuery, fabric) -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.addTabData = function() { - - return { - - fieldList: [], - fieldMap: {}, - autoId: 1, - - _addTabData: function() { - // Here we may need more changes because attributes format likely to change - var tabData = this.options.attributes.tabs; - var that = this; - this.requiredField = []; - var multiplexFieldArray = []; - tabData.forEach(function (tab, tabPointer) { - if (tab["fields"]) { - var tabFields = tab["fields"]; - var fieldArray = []; - var fieldArrayIndex = 0; - // Now we look for fields in the json - for (var field in tabFields) { - var data = tabFields[field]; - - if (!data.id) { - data.id = "Auto" + that.autoId++; - console.log("Field autoassigned id " + data.id); - } - if (!data.type) { - data.type = "text"; - console.log("Field " + data.id + " autoassigned type " + data.type); - } - - var field_val; - if (data.type === "multiplex") { - field_val = that._makeMultiplexField(data, tabPointer, fieldArray); - multiplexFieldArray.push(field_val); - } else { - field_val = that._makeRegularField(data, tabPointer, fieldArray, true); - if (data.type === "multiselect") { - multiplexFieldArray.push(field_val); - } - }; - } - - that.allDataTabs[tabPointer]["fields"] = fieldArray; - } else { - console.log("unknown format in field initialization"); - } - }); - that.multipleFieldList = multiplexFieldArray; - }, - - _makeSubField: function (data, tabPointer, fieldArray) { - var that = this; - if (!data.id) { - data.id = "Auto" + that.autoId++; - console.log("Field autoassigned id " + data.id); - } - if (!data.type) { - data.type = "text"; - console.log("Field " + data.id + " autoassigned type " + data.type); - } - var wrapperDiv = that._createElement("<div></div>").addClass("plate-setup-tab-default-field"); - var wrapperDivLeftSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"); - var wrapperDivRightSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-right-side"); - var nameContainer = that._createElement("<div></div>").addClass("plate-setup-tab-name").text(data.name); - var fieldContainer = that._createElement("<div></div>").addClass("plate-setup-tab-field-container"); - - $(wrapperDivRightSide).append(nameContainer); - $(wrapperDivRightSide).append(fieldContainer); - $(wrapperDiv).append(wrapperDivLeftSide); - $(wrapperDiv).append(wrapperDivRightSide); - $(that.allDataTabs[tabPointer]).append(wrapperDiv); - - var field = { - id: data.id, - name: data.name, - root: wrapperDiv, - data: data, - required: data.required || false - }; - - fieldArray.push(field); - that.fieldMap[data.id] = field; - - return field; - }, - - _makeRegularField: function (data, tabPointer, fieldArray, checkbox){ - var that = this; - var wrapperDiv = that._createElement("<div></div>").addClass("plate-setup-tab-default-field"); - var wrapperDivLeftSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"); - var wrapperDivRightSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-right-side "); - var nameContainer = that._createElement("<div></div>").addClass("plate-setup-tab-name").text(data.name); - var fieldContainer = that._createElement("<div></div>").addClass("plate-setup-tab-field-container"); - - wrapperDivRightSide.append(nameContainer); - wrapperDivRightSide.append(fieldContainer); - wrapperDiv.append(wrapperDivLeftSide); - wrapperDiv.append(wrapperDivRightSide); - that.allDataTabs[tabPointer].append(wrapperDiv); - - var field = { - id: data.id, - name: data.name, - root: wrapperDiv, - data: data, - required: data.required - }; - - if (field.required) { - that.requiredField.push(field.id); - } - - fieldArray.push(field); - that.fieldList.push(field); - that.fieldMap[field.id] = field; - - // Adding checkbox - if (checkbox) { - that._addCheckBox(field); - } - that._createField(field); - - field.onChange = function () { - var v = field.getValue(); - var data = {}; - data[field.id] = v; - that._addAllData(data); - }; - return field; - }, - - _makeMultiplexField: function (data, tabPointer, fieldArray) { - var that = this; - var wrapperDiv = that._createElement("<div></div>").addClass("plate-setup-tab-default-field"); - var wrapperDivLeftSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"); - var wrapperDivRightSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-right-side "); - var nameContainer = that._createElement("<div></div>").addClass("plate-setup-tab-name").text(data.name); - var fieldContainer = that._createElement("<div></div>").addClass("plate-setup-tab-field-container"); - - wrapperDivRightSide.append(nameContainer); - wrapperDivRightSide.append(fieldContainer); - wrapperDiv.append(wrapperDivLeftSide); - wrapperDiv.append(wrapperDivRightSide); - that.allDataTabs[tabPointer].append(wrapperDiv); - - var field = { - id: data.id, - name: data.name, - root: wrapperDiv, - data: data, - required: data.required - }; - - fieldArray.push(field); - that.fieldList.push(field); - that.fieldMap[data.id] = field; - - var subFieldList = []; - //create subfields - var requiredSubField = []; - for (var subFieldKey in data.multiplexFields) { - var subFieldData = data.multiplexFields[subFieldKey]; - var subField = that._makeSubField(subFieldData, tabPointer, fieldArray); - subFieldList.push(subField); - - // stores required subField - if (subFieldData.required) { - requiredSubField.push(subField.id); - } - } - - //store required field - if (field.required || requiredSubField.length) { - this.requiredField.push ({ - multiplexId: field.id, - subFields: requiredSubField - }); - } - - field.subFieldList = subFieldList; - that._createField(field); - that._addCheckBox(field); - - subFieldList.forEach(function (subfield) { - subfield.mainMultiplexField = field; - fieldArray.push(subfield); - that._createField(subfield); - that._addCheckBox(subfield); - delete that.defaultWell[subfield.id]; - // overwrite subField setvalue - subfield.onChange = function () { - var v = subfield.getValue(); - var mainRefField = subfield.mainMultiplexField; - var curId = mainRefField.singleSelectValue(); - //var curDataLs = mainRefField.detailData; - var curVal = {}; - curVal[mainRefField.id] = curId; - //append subfields - curVal[subfield.id] = v; - var returnVal = { - id: curId, - value: curVal - }; - - field._changeMultiFieldValue(returnVal, null); - var curDataLs = mainRefField.detailData; - if (curDataLs !== null) { - curId = mainRefField.singleSelectValue(); - curDataLs = curDataLs.map(function(curData) { - if (curData[mainRefField.id] === curId) { - curData[subfield.id] = v; - } - return curData; - }); - } - mainRefField.detailData = curDataLs; - }; - - }); - - field.getValue = function(){ - var v = field.input.select2('data'); - if (v.length) { - return v.map(function (i) { - return i.id; - }); - } - return null; - }; - - return field; - } - } - } - -})(jQuery, fabric); - -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.addWarningMsg = function () { - // For those check boxes associated with every field in the tab - return { - fieldWarningMsg: function (field, text, include) { - var that = this; - var imgId = "fieldWarning" + field.id; - var img = $("<span>").html(that._assets.warningImg).attr("id", imgId).addClass("plate-field-warning-image"); - //field.root.find(".plate-setup-tab-name").append('<img id="theImg" src="theImg.png" />') - if (include) { - if (field.root.find("#" + imgId).length <= 0){ - field.root.find(".plate-setup-tab-name").text(" " + field.name); - field.root.find(".plate-setup-tab-name").prepend(img); - - var popText = $("<div/>").addClass("pop-out-text"); - popText.text(text); - field.root.find(".plate-setup-tab-name").append(popText); - - $("#" + imgId).hover(function (e) { - popText[0].style.display = 'flex'; - }, function () { - popText.hide(); - }); - } - - - } else { - if (field.root.find("#" + imgId).length > 0) { - field.root.find(".plate-setup-tab-name").text(field.name); - $("#" + imgId).remove(); - } - } - }, - - removeWarningMsg: function (field, text, include) { - var that = this; - var imgId = "fieldWarning" + field.id; - var img = $("<span>").html(that._assets.warningImg).attr("id", imgId).addClass("plate-field-warning-image"); - //field.root.find(".plate-setup-tab-name").append('<img id="theImg" src="theImg.png" />') - if (include) { - field.root.find(".plate-setup-tab-name").append(img); - - var popText = $("<div/>").addClass("pop-out-text"); - popText.text(text); - field.root.find(".plate-setup-tab-name").append(popText); - - $("#" + imgId).hover(function (e) { - popText[0].style.display = 'inline-block'; - }, function () { - popText.hide(); - }); - - } else { - $("#" + imgId).remove(); - if (field.root.find("#" + imgId).length > 0) { - //field.root.find(".plate-setup-tab-name").remove(img); - $("#" + imgId).remove(); - } - } - }, - - applyFieldWarning: function(wells) { - var that = this; - var req = 0; - var fill = 0; - var fieldData = {}; - that.fieldList.forEach(function(field){ - fieldData[field.id] = []; - }); - wells.forEach(function(well){ - if (!that.engine.wellEmpty(well)){ - for (var fieldId in fieldData) { - if (fieldId in well) { - fieldData[fieldId].push(well[fieldId]); - } else { - fieldData[fieldId].push(null); - } - } - } - }); - for (var i = 0; i < that.fieldList.length; i++) { - var field = that.fieldList[i]; - if (field.applyMultiplexSubFieldColor){ - field.applyMultiplexSubFieldColor(fieldData[field.id]); - } else { - if (field.required) { - var include = false; - fieldData[field.id].forEach(function(val){ - // for multiselect - if (val instanceof Array) { - if (val.length === 0) { - include = true; - } - } else { - if (val === null) { - include = true; - } - } - }); - //field.root.find(".plate-setup-tab-name").css("background", color); - that.fieldWarningMsg(field, "required field", include); - } - } - } - } - } - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.bottomTable = function() { - // for bottom table - return { - _bottomScreen: function() { - this.bottomContainer = this._createElement("<div></div>").addClass("plate-setup-bottom-container"); - this.bottomTableContainer = this._createElement("<div></div>").addClass("plate-setup-bottom-table-container"); - this.bottomTable = this._createElement("<table></table>").addClass("plate-setup-bottom-table"); - this.bottomTableContainer.append(this.bottomTable); - this.bottomContainer.append(this.bottomTableContainer); - this.container.append(this.bottomContainer); - }, - - addBottomTableHeadings: function() { - - this.bottomRow = this._createElement("<tr></tr>"); - - var singleField = this._createElement("<th></th>") - .text("Group"); - this.bottomRow.prepend(singleField); - // Now we append all the captions at the place. - this.bottomTable.empty(); - this.bottomTable.append(this.bottomRow); - - this.rowCounter = 1; - - for (var i = 0; i < this.globalSelectedAttributes.length; i++) { - var attr = this.globalSelectedAttributes[i]; - var field = this.fieldMap[attr]; - var singleField = this._createElement("<th></th>").text(field.name); - this.bottomRow.append(singleField); - this.rowCounter = this.rowCounter + 1; - } - - this.adjustFieldWidth(this.bottomRow); - }, - - tileAttrText: function(tile, attr) { - var well = this.engine.derivative[tile.index]; - var field = this.fieldMap[attr]; - return field.getText(well[attr]); - }, - - addBottomTableRow: function(color, singleStack) { - var that = this; - var modelTile = this.allTiles[singleStack[0]]; - var row = this._createElement("<tr></tr>"); - var plateIdDiv = this._createElement("<td></td>").addClass("plate-setup-bottom-id"); - var numberText = this._createElement("<button/>"); - numberText.addClass("plate-setup-color-text"); - numberText.text(color); - plateIdDiv.append(numberText); - - numberText.click(function(evt){ - var addressToSelect = singleStack.map(function(addressIdx){ - return that.indexToAddress(addressIdx) - }); - if (evt.ctrlKey) { - that.getSelectedAddress().forEach(function(val){ - if (addressToSelect.indexOf(val) < 0){ - addressToSelect.push(val); - } - }) - } - that.setSelectedWell(addressToSelect); - that._trigger("selectedWells", null, {selectedAddress: that.getSelectedAddress()}); - }); - - if (color > 0) { - color = ((color - 1) % (this.colorPairs.length - 1)) + 1; - } - var colorStops = this.colorPairs[color]; - - plateIdDiv.css("background", "linear-gradient(to right, " + colorStops[0] + " , " + colorStops[1] + ")"); - - row.append(plateIdDiv); - - for (var i = 0; i < this.globalSelectedAttributes.length; i++) { - var attr = this.globalSelectedAttributes[i]; - var text = this.tileAttrText(modelTile, attr); - var dataDiv = this._createElement("<td></td>").text(text); - row.append(dataDiv); - } - this.bottomTable.append(row); - this.adjustFieldWidth(row); - }, - - bottomForFirstTime: function() { - this.addBottomTableHeadings(); - // This is executed for the very first time.. ! - var row = this._createElement("<tr></tr>"); - - var colorStops = this.colorPairs[0]; - var plateIdDiv = this._createElement("<td></td>"); - plateIdDiv.css("background", "-webkit-linear-gradient(left, " + colorStops[0] + " , " + colorStops[1] + ")"); - row.append(plateIdDiv); - this.bottomTable.append(row); - this.createExportButton(); - }, - - adjustFieldWidth: function(row) { - - var length = this.rowCounter; - if ((length) * 150 > 1024) { - row.css("width", (length) * 152 + "px"); - } - }, - - downloadCSV: function(csv, filename) { - var csvFile; - var downloadLink; - - // CSV file - csvFile = new Blob([csv], { - type: "text/csv" - }); - - // Download link - downloadLink = document.createElement("a"); - - // File name - downloadLink.download = filename; - - // Create a link to the file - downloadLink.href = window.URL.createObjectURL(csvFile); - - // Hide download link - downloadLink.style.display = "none"; - - // Add the link to DOM - document.body.appendChild(downloadLink); - - // Click download link - downloadLink.click(); - }, - - exportData: function(format) { - var data = []; - var rows = document.querySelectorAll("table tr"); - - var colorLocMap = {}; - var colorLocIdxMap = this.engine.stackUpWithColor; - var dim = this.getDimensions(); - var that = this; - for (var colorIdx in colorLocIdxMap) { - colorLocMap[colorIdx] = colorLocIdxMap[colorIdx].map(function (locIdx) { - return that.indexToAddress(locIdx, dim); - }) - } - - for (var i = 0; i < rows.length; i++) { - var row = [], - cols = rows[i].querySelectorAll("td, th"); - - for (var j = 0; j < cols.length; j++) { - var v = ""; - if (cols[j].innerText) { - if (format === "csv") { - v = '"' + cols[j].innerText.replace(/"/g, '""') + '"'; - } else { - v = cols[j].innerText; - } - } - row.push(v); - - // add location column - if (i === 0 && j === 0) { - if (format === "csv") { - row.push('"Location"'); - } else if (format === 'clipboard') { - row.push("Location"); - } - - } - if (i !== 0 && j === 0) { - var loc = ''; - if (colorLocMap[parseInt(cols[j].innerText)]) { - if (format === "csv") { - loc = '"' + colorLocMap[parseInt(cols[j].innerText)].join(",") + '"'; - } else if (format === 'clipboard') { - loc = colorLocMap[parseInt(cols[j].innerText)].join(","); - } - } - row.push(loc); - } - } - - if (format === "csv") { - data.push(row.join(",")); - } else if (format === 'clipboard') { - data.push(row.join("\t")); - //data.push(row); // for text type - } - - } - if (format === "csv") { - // Download CSV file - this.downloadCSV(data.join("\n"), 'table.csv'); - } else if (format === 'clipboard') { - //return formatTableToString(data); // for text type - return data.join("\n"); - } - }, - - createExportButton: function() { - var that = this; - var overlayContainer = $("<div>").addClass("plate-setup-bottom-control-container"); - - var descriptionDiv = $("<div>").addClass("plate-setup-overlay-text-container"); - descriptionDiv.text("Color groups"); - overlayContainer.append(descriptionDiv); - - var buttonContainer = $("<div>").addClass("plate-setup-overlay-bottom-button-container"); - - // create export csv option - var exportButton = $("<button/>").addClass("plate-setup-button"); - exportButton.text("Export CSV"); - buttonContainer.append(exportButton); - - exportButton.click(function() { - that.exportData('csv'); - exportButton.text("Exported"); - exportButton[0].classList.remove("plate-setup-button"); - exportButton.addClass("plate-setup-clicked-button"); - setTimeout(resetExportText, 3000); - }); - - function resetExportText() { - exportButton.text("Export CSV"); - exportButton[0].classList.remove("plate-setup-clicked-button"); - exportButton.addClass("plate-setup-button"); - } - - // creat clipboard option, CLipboard is an external js file located in vendor/asset/javascripts - var clipboardButton = $("<button/>").addClass("plate-setup-button"); - clipboardButton.text("Copy To Clipboard"); - buttonContainer.append(clipboardButton); - - var clipboard = new ClipboardJS(clipboardButton.get(0), { - text: function() { - return that.exportData("clipboard"); - } - }); - - clipboard.on('success', function(e) { - clipboardButton.text("Copied as tab-delimited format"); - clipboardButton[0].classList.remove("plate-setup-button"); - clipboardButton.addClass("plate-setup-clicked-button"); - setTimeout(resetClipboardText, 3000); - }); - - function resetClipboardText() { - clipboardButton.text("Copy To Clipboard"); - clipboardButton[0].classList.remove("plate-setup-clicked-button"); - clipboardButton.addClass("plate-setup-button"); - } - - clipboard.on('error', function(e) { - clipboardButton.text("Failed to copy table to clipboard: browser may be incompatible"); - setTimeout(resetClipboardText, 3000); - }); - - overlayContainer.append(buttonContainer); - $(".plate-setup-bottom-container").prepend(overlayContainer); - } - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.canvas = function() { - // - return { - - allSelectedObjects: null, // Contains all the selected objets, when click and drag. - - allPreviouslySelectedObjects: null, - - colorPointer: 0, - - goldenRatio: 0.618033988749895, - - _createCanvas: function() { - this.normalCanvas = this._createElement("<canvas>").attr("id", "DNAcanvas"); - $(this.canvasContainer).append(this.normalCanvas); - }, - - _initiateFabricCanvas: function() { - var w = this.canvasContainer.width(); - var h = this.canvasContainer.height(); - - this._setCanvasArea(w, h); - - this.mainFabricCanvas = new fabric.Canvas('DNAcanvas', { - backgroundColor: '#f5f5f5', - selection: false, - stateful: false, - hoverCursor: "pointer", - renderOnAddRemove: false, - }) - .setWidth(w) - .setHeight(h); - }, - - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.checkBox = function() { - // For those check boxes associated with every field in the tab - return { - - globalSelectedAttributes: [], - - _addCheckBox: function(field) { - var checkImage = $("<span>").html(this._assets.dontImg).addClass("plate-setup-tab-check-box bg-light") - .data("clicked", false); - checkImage.data("linkedFieldId", field.id); - field.root.find(".plate-setup-tab-field-left-side").empty().append(checkImage); - this._applyCheckboxHandler(checkImage); // Adding handler for change the image when clicked - field.checkbox = checkImage; - }, - - _applyCheckboxHandler: function(checkBoxImage) { - // We add checkbox handler here, thing is it s not checkbox , its an image and we change - // source - var that = this; - checkBoxImage.click(function(evt, machineClick) { - var checkBox = $(this); - - var changes = {}; - changes[checkBox.data("linkedFieldId")] = !checkBox.data("clicked"); - - that.changeCheckboxes(changes); - }); - }, - - changeSubFieldsCheckboxes: function(field, changes) { - var that = this; - var subFieldToInclude = []; - - field.subFieldList.forEach(function(subField) { - var checkImage = subField.checkbox; - var fieldId = checkImage.data("linkedFieldId"); - var clicked = checkImage.data("clicked"); - if (fieldId in changes) { - clicked = Boolean(changes[fieldId]); - } - checkImage.data("clicked", clicked); - if (clicked) { - checkImage.html(that._assets.doImg); - subFieldToInclude.push(subField.id); - } else { - checkImage.html(that._assets.dontImg); - } - }); - return subFieldToInclude; - }, - - changeCheckboxes: function(changes) { - var gsa = []; - var multiplexCheckedSubField = {}; - for (var i = 0; i < this.fieldList.length; i++) { - var field = this.fieldList[i]; - if (field.checkbox) { - if (field.subFieldList) { - multiplexCheckedSubField[field.id] = this.changeSubFieldsCheckboxes(field, changes); - } - - var checkImage = field.checkbox; - var fieldId = checkImage.data("linkedFieldId"); - var clicked = checkImage.data("clicked"); - if (fieldId in changes) { - clicked = Boolean(changes[fieldId]); - } - checkImage.data("clicked", clicked); - if (clicked) { - gsa.push(fieldId); - checkImage.html(this._assets.doImg); - } else { - checkImage.html(this._assets.dontImg); - } - } - } - this.globalSelectedMultiplexSubfield = multiplexCheckedSubField; - this.globalSelectedAttributes = gsa; - this._clearPresetSelection(); - this._colorMixer(); - }, - - setSubFieldCheckboxes: function(field, fieldIds) { - var that = this; - var subFieldToInclude = []; - field.subFieldList.forEach(function(subField) { - var checkImage = subField.checkbox; - var fieldId = checkImage.data("linkedFieldId"); - var clicked = fieldIds.indexOf(fieldId) >= 0; - checkImage.data("clicked", clicked); - if (clicked) { - checkImage.html(that._assets.doImg); - subFieldToInclude.push(subField.id); - } else { - checkImage.html(that._assets.dontImg); - } - }); - return subFieldToInclude; - }, - - setCheckboxes: function(fieldIds) { - fieldIds = fieldIds || []; - var gsa = []; - var multiplexCheckedSubField = {}; - - for (var i = 0; i < this.fieldList.length; i++) { - var field = this.fieldList[i]; - if (field.checkbox) { - // special handling for multiplex field - if (field.subFieldList) { - multiplexCheckedSubField[field.id] = this.setSubFieldCheckboxes(field, fieldIds); - } - - var checkImage = field.checkbox; - var fieldId = checkImage.data("linkedFieldId"); - var clicked = fieldIds.indexOf(fieldId) >= 0; - checkImage.data("clicked", clicked); - if (clicked) { - gsa.push(fieldId); - checkImage.html(this._assets.doImg); - } else { - - checkImage.html(this._assets.dontImg); - } - } - } - this.globalSelectedMultiplexSubfield = multiplexCheckedSubField; - this.globalSelectedAttributes = gsa; - this._clearPresetSelection(); - this._colorMixer(); - } - - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.colorManager = function() { - - return { - // See these are color pairs for the gradient. - colorPairs: [ - ["#e6e6e6", "#808080"], - ["#66e8ff", "#0082c8"], - ["#ff7fb1", "#e6194b"], - ["#a2ffb1", "#3cb44b"], - ["#f784ff", "#911eb4"], - ["#ffe897", "#f58231"], - ["#6666ff", "#0000FF"], - ["#ffff7f", "#ffe119"], - ["#acffff", "#46f0f0"], - ["#ff98ff", "#f032e6"], - ["#ffffa2", "#d2f53c"], - ["#ffffff", "#fabebe"], - ["#66e6e6", "#008080"], - ["#ffffff", "#e6beff"], - ["#ffd48e", "#aa6e28"], - ["#e66666", "#800000"], - ["#ffffff", "#aaffc3"], - ["#e6e666", "#808000"], - ["#ffffff", "#ffd8b1"], - ["#66a9ef", "#004389"], - ["#ff6672", "#a7000c"], - ["#66db72", "#00750c"], - ["#b866db", "#520075"], - ["#ffa966", "#b64300"], - ["#ffff66", "#c0a200"], - ["#6dffff", "#07b1b1"], - ["#ff66ff", "#b100a7"], - ["#f9ff66", "#93b600"], - ["#ffe5e5", "#bb7f7f"], - ["#66a7a7", "#004141"], - ["#ffe5ff", "#a77fc0"], - ["#d19566", "#6b2f00"], - ["#ffffef", "#c0bb89"], - ["#d1ffea", "#6bc084"], - ["#a7a766", "#414100"], - ["#ffffd8", "#c09972"], - ["#a5ffff", "#3fc1ff"], - ["#ffbef0", "#ff588a"], - ["#e1fff0", "#7bf38a"], - ["#ffc3ff", "#d05df3"], - ["#ffffd6", "#ffc170"], - ["#a5a5ff", "#3f3fff"], - ["#ffffbe", "#ffff58"], - ["#ebffff", "#85ffff"], - ["#ffd7ff", "#ff71ff"], - ["#a5ffff", "#3fbfbf"], - ["#ffffcd", "#e9ad67"], - ["#ffa5a5", "#bf3f3f"], - ["#ffffa5", "#bfbf3f"] - ] - } - } - -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.createCanvasElements = function() { - // this class manages creating all the elements within canvas - return { - - scaleFactor: 1, - - baseSizes: { - spacing: 48, - tile_radius: 22, - center_radius_complete: 10, - center_radius_incomplete: 14, - label_size: 14, - label_spacing: 24, - text_size: 13, - stroke: 0.5, - gap: 2 - }, - - _setCanvasArea: function(w, h) { - this.scaleFactor = Math.min( - h / (this.dimensions.rows * this.baseSizes.spacing + this.baseSizes.label_spacing), - w / (this.dimensions.cols * this.baseSizes.spacing + this.baseSizes.label_spacing)); - - var sizes = {} - for (var prop in this.baseSizes) { - sizes[prop] = this.baseSizes[prop] * this.scaleFactor; - } - this.sizes = sizes; - }, - - _canvas: function() { - // Those 1,2,3 s and A,B,C s - this._fixRowAndColumn(); - - // All those circles in the canvas. - this._putCircles(); - }, - - _fixRowAndColumn: function() { - var cols = this.dimensions.cols; - var rows = this.dimensions.rows; - - var spacing = this.sizes.spacing; - var d1 = this.sizes.label_spacing / 2; - var d2 = this.sizes.label_spacing + this.sizes.spacing / 2; - var fontSize = this.sizes.label_size; - - // For column - var top = d1; - var left = d2; - for (var i = 1; i <= cols; i++) { - var tempFabricText = new fabric.IText(i.toString(), { - fill: 'black', - originX: 'center', - originY: 'center', - fontSize: fontSize, - top: top, - left: left, - fontFamily: '"Roboto", Arial, sans-serif', - selectable: false, - fontWeight: "400" - }); - left += spacing; - - this.mainFabricCanvas.add(tempFabricText); - } - - // for row - top = d2; - left = d1; - for (var i = 1; i <= rows; i++) { - var tempFabricText = new fabric.IText(this.rowIndex[i-1], { - fill: 'black', - originX: 'center', - originY: 'center', - fontSize: fontSize, - top: top, - left: left, - fontFamily: '"Roboto", Arial, sans-serif', - selectable: false, - fontWeight: "400" - }); - top += spacing; - - this.mainFabricCanvas.add(tempFabricText); - } - }, - - _putCircles: function() { - var cols = this.dimensions.cols; - var rows = this.dimensions.rows; - - var tileCounter = 0; - for (var row = 0; row < rows; row++) { - for (var col = 0; col < cols; col++) { - var index = this.allTiles.length; - var tile = this._createTile(row, col); - tile.index = tileCounter++; - this.allTiles.push(tile); - this.mainFabricCanvas.add(tile.background); - this.mainFabricCanvas.add(tile.highlight); - this.mainFabricCanvas.add(tile.circle); - this.mainFabricCanvas.add(tile.circleCenter); - this.mainFabricCanvas.add(tile.circleText); - } - } - - this._addLargeRectangleOverlay(); - this._fabricEvents(); - }, - - _createTile: function (row, col) { - var tile = {}; - - tile.visible = false; - tile.colorIndex = null; - tile.row = row; - tile.col = col; - tile.address = this.rowIndex[row] + (col + 1); - - var top = (row + 1) * this.sizes.spacing; - var left = (col + 1) * this.sizes.spacing; - - tile.background = new fabric.Circle({ - top: top, - left: left, - radius: this.sizes.tile_radius, - originX: 'center', - originY: 'center', - hasControls: false, - hasBorders: false, - lockMovementX: true, - lockMovementY: true, - evented: false, - }); - - tile.background.setGradient("fill", { - type: "radial", - x1: this.sizes.tile_radius, - x2: this.sizes.tile_radius, - y1: this.sizes.tile_radius + this.sizes.gap, - y2: this.sizes.tile_radius + this.sizes.gap, - r1: this.sizes.tile_radius - this.sizes.gap, - r2: this.sizes.tile_radius, - colorStops: { - 0: 'rgba(0,0,0,0.1)', - 1: 'rgba(0,0,0,0.2)' - } - }); - - tile.highlight = new fabric.Rect({ - originX: 'center', - originY: 'center', - top: top, - left: left, - width: this.sizes.spacing, - height: this.sizes.spacing, - fill: "rgba(0,0,0,0.4)", - evented: false, - visible: false - }); - - tile.circle = new fabric.Circle({ - originX: 'center', - originY: 'center', - top: top, - left: left, - radius: this.sizes.tile_radius, - stroke: 'gray', - strokeWidth: this.sizes.stroke, - evented: false, - visible: false - }); - - tile.circleCenter = new fabric.Circle({ - originX: 'center', - originY: 'center', - top: top, - left: left, - radius: this.sizes.center_radius_incomplete, - fill: "white", - stroke: 'gray', - strokeWidth: this.sizes.stroke, - evented: false, - visible: false - }); - - tile.circleText = new fabric.IText("", { - originX: 'center', - originY: 'center', - top: top, - left: left, - fill: 'black', - fontFamily: '"Roboto", Arial, sans-serif', - fontSize: this.sizes.text_size, - lockScalingX: true, - lockScalingY: true, - evented: false, - visible: false - }); - - return tile; - }, - - setTileComplete: function (tile, complete) { - if (complete) { - tile.circleCenter.radius = this.sizes.center_radius_complete; - tile.circleText.fill = "black"; - tile.circleText.fontWeight = 'normal'; - } else { - tile.circleCenter.radius = this.sizes.center_radius_incomplete; - tile.circleText.fill = "red"; - tile.circleText.fontWeight = 'bold'; - } - }, - - setTileVisible: function (tile, visible) { - tile.visible = visible; - tile.circle.visible = tile.visible; - tile.circleCenter.visible = tile.visible; - tile.circleText.visible = tile.visible; - }, - - setTileColor: function(tile, color, stackPointer) { - this.setTileVisible(tile, true); - tile.colorIndex = parseInt(color); - tile.circleText.text = String(tile.colorIndex); - - if (color > 0) { - color = ((color - 1) % (this.colorPairs.length -1)) + 1; - } - var colorStops = this.colorPairs[color]; - - tile.circle.setGradient("fill", { - y2: 2 * this.sizes.tile_radius, - colorStops: colorStops - }); - }, - - _addLargeRectangleOverlay: function() { - - this.overLay = new fabric.Rect({ - width: 632, - height: 482, - left: 0, - top: 0, - opacity: 0.0, - originX: 'left', - originY: 'top', - lockMovementY: true, - lockMovementX: true, - selectable: false - }); - - this.mainFabricCanvas.add(this.overLay); - } - }; - } -})(jQuery, fabric); - -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.createField = function() { - // It create those fields in the tab , there is 4 types of them. - return { - - _createField: function(field) { - switch (field.data.type) { - case "text": - this._createTextField(field); - break; - - case "numeric": - this._createNumericField(field); - break; - - case "select": - this._createSelectField(field); - break; - - case "multiselect": - this._createMultiSelectField(field); - break; - - case "boolean": - this._createBooleanField(field); - break; - - case "multiplex": - this._createMultiplexField(field); - break; - } - }, - - _createTextField: function(field) { - var id = field.id; - var that = this; - var input = this._createElement("<input>").attr("id", id) - .addClass("plate-setup-tab-input"); - - field.root.find(".plate-setup-tab-field-container").append(input); - that.defaultWell[id] = null; - - field.parseValue = function(v) { - if (v) { - v = String(v); - } else { - v = null; - } - return v; - }; - - field.getValue = function() { - var v = input.val().trim(); - if (v == "") { - v = null; - } - return v; - }; - - field.setValue = function(v) { - input.val(v); - }; - - field.getText = function(v) { - if (v == null) { - return ""; - } - return v; - }; - - field.disabled = function(bool) { - field.input.prop("disabled", bool); - }; - - field.parseText = field.parseValue; - - input.on("input", function(e, generated) { - field.onChange(); - }); - - field.input = input; - }, - - _createOpts: function(config) { - var opts = { - allowClear: true, - placeholder: "select", - minimumResultsForSearch: 10 - }; - - if (config.options) { - opts.data = config.options; - } else if (config.query) { - var query = config.query; - if (config.delay) { - query = this._debounce(config.delay, query); - } - opts.query = query; - } else { - throw "Must specify data or query"; - } - return opts; - }, - - _createSelectField: function(field) { - var id = field.id; - var that = this; - var input = this._createElement("<input/>").attr("id", id) - .addClass("plate-setup-tab-select-field"); - - field.root.find(".plate-setup-tab-field-container").append(input); - that.defaultWell[id] = null; - - var opts = that._createOpts(field.data); - var optMap = {}; - opts.data.forEach(function(opt) { - optMap[opt.id] = opt; - }); - - input.select2(opts); - - field.parseValue = function(value) { - var v = value; - - if (v == "") { - v = null; - } - if (v == null) { - return null; - } - if (v in optMap) { - return optMap[v].id; - } else { - throw "Invalid value " + value + " for select field " + id; - } - }; - - field.disabled = function(bool) { - field.input.prop("disabled", bool); - }; - - field.getValue = function() { - var v = input.select2('data'); - return v ? v.id : null; - }; - - field.setValue = function(v) { - if (v) { - v = optMap[v]; - } - input.select2('data', v); - }; - - field.setOpts = function(v) { - input.select2('data', {}); - opts.data = v || []; - input.select2(opts); - }; - - field.getText = function(v) { - if (v == null) { - return ""; - } - return optMap[v].text; - }; - - field.parseText = function(value) { - var v = value; - - if (v == "") { - v = null; - } - if (v == null) { - return null; - } - if (v in optMap) { - return optMap[v].text; - } else { - throw "Invalid text value " + value + " for select field " + id; - } - }; - - input.on("change", function(e, generated) { - field.onChange(); - }); - - field.input = input; - }, - - _createMultiSelectField: function(field) { - var id = field.id; - var that = this; - var input = this._createElement("<input/>").attr("id", id) - .addClass("plate-setup-tab-multiselect-field"); - input.attr("multiple", "multiple"); - - field.root.find(".plate-setup-tab-field-container").append(input); - that.defaultWell[id] = null; - - var separator = ","; - var opts = that._createOpts(field.data); - opts.multiple = true; - var optMap = {}; - opts.data.forEach(function(opt) { - optMap[opt.id] = opt; - }); - input.select2(opts); - - field.disabled = function(bool) { - field.input.prop("disabled", bool); - }; - - field.parseValue = function(value) { - var v = value; - if (v && v.length) { - v = v.map(function(opt) { - if (opt in optMap) { - return optMap[opt].id; - } else { - throw "Invalid value " + opt + " for multiselect field " + id; - } - }); - } else { - v = null; - } - return v; - }; - - field.setOpts = function(v) { - var allOpts = field.data.options; - var selectedVal = []; - for (var id in allOpts) { - var curOpts = allOpts[id]; - if (v.indexOf(curOpts["id"]) >= 0) { - selectedVal.push(curOpts); - } - } - - opts.data = selectedVal; - input.select2(opts); - }; - - field.getValue = function() { - var v = input.select2('data'); - if (v.length) { - return v.map(function(i) { - return i.id; - }); - } - return null; - }; - - field.setValue = function(v) { - v = v || []; - v = v.map(function(i) { - return optMap[i]; - }); - input.select2('data', v); - }; - - field.getText = function(v) { - if (v == null) { - return ""; - } - if (v.length > 0) { - return v.map(function(v) { - return optMap[v].text - }).join("; "); - } - return ""; - }; - - field.multiOnChange = function (added, removed) { - if (added) { - added = added.id.toString(); - } - if (removed) { - removed = removed.id.toString(); - } - var data = { - }; - data[field.id] = { - multi: true, - added: added, - removed: removed - }; - - that._addAllData(data); - }; - - field.parseText = function(value){ - var v = value; - if (v && v.length) { - v = v.map(function(opt) { - if (opt in optMap) { - return optMap[opt].text; - } else { - throw "Invalid text value " + opt + " for multiselect field " + id; - } - }); - } else { - v = null; - } - return v; - }; - - input.on("change", function(e, generated) { - var added = e.added; - var removed = e.removed; - //field.onChange(); - field.multiOnChange(added, removed); - }); - - field.input = input; - - that._createDeleteButton(field); - }, - - _createNumericField: function(field) { - var id = field.id; - var data = field.data; - var that = this; - var input = this._createElement("<input>").addClass("plate-setup-tab-input") - .attr("placeholder", data.placeholder || "").attr("id", id); - - field.root.find(".plate-setup-tab-field-container").append(input); - that.defaultWell[id] = null; - - // Adding unit - var units = data.units || []; - var defaultUnit = data.defaultUnit || null; - var unitInput = null; - if (defaultUnit) { - if (units.length) { - if (units.indexOf(defaultUnit) < 0) { - defaultUnit = units[0]; - } - } else { - units = [defaultUnit]; - } - } else { - if (units.length) { - defaultUnit = units[0]; - } - } - - if (units.length) { - field.units = units; - field.hasUnits = true; - field.defaultUnit = defaultUnit; - if (units.length == 1) { - var unitText = $("<div></div>").addClass("plate-setup-tab-unit"); - unitText.text(defaultUnit); - field.root.find(".plate-setup-tab-field-container").append(unitText); - } else { - unitInput = this._createElement("<input/>").attr("id", id) - .addClass("plate-setup-tab-label-select-field"); - - field.root.find(".plate-setup-tab-field-container").append(unitInput); - - var selected = null; - var unitData = units.map(function(unit) { - var o = { - id: unit, - text: unit - }; - if (unit == defaultUnit) { - selected = o; - } - return o; - }); - - var opts = { - data: unitData, - allowClear: false, - minimumResultsForSearch: 10 - }; - - unitInput.select2(opts); - unitInput.select2("data", selected); - } - } - - field.disabled = function(bool) { - field.input.prop("disabled", bool); - if (unitInput) { - unitInput.prop("disabled", bool); - } - }; - - field.setUnitOpts = function(opts) { - field.units = opts || null; - field.defaultUnit = null; - - var newUnits = []; - var selected = null; - if (field.units && field.units.length) { - field.defaultUnit = field.units[0]; - newUnits = field.units.map(function(curUnit) { - var cleanUnit = { - id: curUnit, - text: curUnit - }; - if (curUnit == field.defaultUnit) { - selected = cleanUnit; - } - return cleanUnit; - }); - } - - var newOpts = { - data: newUnits, - allowClear: false, - minimumResultsForSearch: 10 - }; - unitInput.select2(newOpts); - unitInput.select2("data", selected); - }; - - field.parseValue = function(value) { - var v; - if ($.isPlainObject(value)) { - if (field.hasUnits) { - v = field.parseRegularValue(value.value); - if (v === null) { - return null; - } - return { - value: v, - unit: field.parseUnit(value.unit) - }; - } else { - throw "Value must be plain numeric for numeric field " + id; - } - } else { - if (field.hasUnits) { - v = field.parseRegularValue(value); - if (v === null) { - return null; - } - return { - value: v, - unit: field.defaultUnit - }; - } else { - return field.parseRegularValue(value); - } - } - }; - - field.getValue = function() { - var v = field.getRegularValue(); - - if ((v === null) || isNaN(v)) { - return null; - } else if (field.hasUnits) { - var returnVal = { - value: v, - unit: field.getUnit() - }; - - if (field.data.hasMultiplexUnit) { - // include unitTypeId and UnitId to returnVal - for (var unitTypeKey in field.data.unitMap) { - var unitTypeUnits = field.data.unitMap[unitTypeKey]; - unitTypeUnits.forEach(function(unit) { - if (unit.text === returnVal.unit) { - returnVal['unitTypeId'] = unitTypeKey; - returnVal['unitId'] = unit.id; - } - }) - } - } - return returnVal; - } else { - return v; - } - }; - - field.setValue = function(value) { - if (field.hasUnits) { - if ($.isPlainObject(value)) { - field.setUnit(value.unit || field.defaultUnit); - field.setRegularValue(value.value); - - } else { - field.setRegularValue(value); - field.setUnit(field.defaultUnit) - } - } else { - field.setRegularValue(value); - } - }; - - field.parseRegularValue = function(value) { - if (value == null) { - return null; - } - var v = String(value).trim(); - if (v === "") { - return null; - } - v = Number(value); - if (isNaN(v)) { - throw "Invalid value " + value + " for numeric field " + id; - } - return v; - }; - - field.getRegularValue = function() { - var v = input.val().trim(); - if (v == "") { - v = null; - } else { - v = Number(v); - } - return v; - }; - - field.setRegularValue = function(value) { - input.val(value); - }; - - field.parseUnit = function(unit) { - if (unit == null || unit === "") { - return field.defaultUnit; - } - for (var i = 0; i < units.length; i++) { - if (unit.toLowerCase() == units[i].toLowerCase()) { - return units[i]; - } - } - throw "Invalid unit " + unit + " for field " + id; - }; - - field.getUnit = function() { - if (unitInput) { - return unitInput.val(); - } else { - return field.defaultUnit; - } - }; - - field.setUnit = function(unit) { - if (unitInput) { - unit = unit || field.defaultUnit; - if (unit != null) { - unit = { - id: unit, - text: unit - }; - } - unitInput.select2("data", unit); - } - }; - - // val now contains unit - field.getText = function(val) { - if (typeof(val) === 'object' && val) { - var v = val.value; - var u = val.unit; - if (v == null) { - return ""; - } - v = v.toString(); - if (!u) { - u = defaultUnit; - } - if (u) { - v = v + " " + u; - } - return v; - } else { - return field.getRegularText(val); - } - }; - - field.getRegularText = function(v) { - if (v == null) { - return ""; - } - v = v.toString(); - return v; - }; - - field.parseText = function(v){ - var textVal = field.parseValue(v); - if (textVal && typeof(textVal) === "object"){ - return textVal.value + textVal.unit; - } else if (textVal) { - return textVal - } else { - return null; - } - }; - - input.on("input", function() { - var v = field.getRegularValue(); - if (isNaN(v)) { - //flag field as invalid - input.addClass("invalid"); - } else { - input.removeClass("invalid"); - } - field.onChange(); - }); - if (unitInput) { - unitInput.on("change", function() { - field.onChange(); - }); - } - - field.input = input; - field.unitInput = unitInput; - }, - - _createBooleanField: function(field) { - var id = field.id; - var that = this; - var input = this._createElement("<input/>").attr("id", id) - .addClass("plate-setup-tab-select-field"); - that.defaultWell[id] = null; - - field.root.find(".plate-setup-tab-field-container").append(input); - var tval = { - id: "true", - text: "true" - }; - var fval = { - id: "false", - text: "false" - }; - var opts = { - data: [tval, fval], - placeholder: "select", - allowClear: true, - minimumResultsForSearch: -1, - initSelection: function(element, callback) { - var v = element.val(); - callback({ - id: v, - text: v - }); - } - }; - - input.select2(opts); - - field.disabled = function(bool) { - field.input.prop("disabled", bool); - }; - - field.parseValue = function(value) { - if (value == null) { - return null; - } - var v = String(value).trim().toLowerCase(); - if (v == "true") { - v = true; - } else if (v == "false") { - v = false; - } else if (v == "") { - v = null; - } else { - throw "Invalid value " + value + " for boolean field " + id; - } - return v; - }; - - field.getValue = function() { - var v = input.val(); - switch (v) { - case "true": - return true; - case "false": - return false; - default: - return null; - } - }; - - field.setValue = function(v) { - if (v == true || v == "true") { - v = tval; - } else if (v == false || v == "false") { - v = fval; - } else { - v = null; - } - input.select2('data', v); - }; - - field.getText = function(v) { - if (v == null) { - return ""; - } - return v.toString(); - }; - - field.parseText = field.parseValue; - - input.on("change", function(e) { - field.onChange(); - }); - - field.input = input; - }, - - _createMultiplexField: function(field) { - var that = this; - // make correct multiplex data - this._createMultiSelectField(field); - // overwrite default well for multiplex field - that.defaultWell[field.id] = []; - - // single select - var nameContainer1 = that._createElement("<div></div>").addClass("plate-setup-tab-name-singleSelect").text("Select to edit"); - var fieldContainer1 = that._createElement("<div></div>").addClass("plate-setup-tab-field-container-singleSelect"); - field.root.find(".plate-setup-tab-field-right-side").append(nameContainer1, fieldContainer1); - - field.singleSelect = this._createElement("<input/>").attr("id", field.id + "SingleSelect") - .addClass("plate-setup-tab-multiplex-single-select-field"); - - field.singleSelect.appendTo(fieldContainer1); - - field.singleSelectValue = function () { - var v = field.singleSelect.select2("data"); - if (v != null) { - v = v.id; - } - return v; - }; - - var setSingleSelectOptions = function (v, selected_v) { - var opts = { - allowClear: false, - placeholder: "select", - minimumResultsForSearch: 10, - data: v || [] - } - if (!selected_v) { - if (opts.data.length) { - selected_v = opts.data[0]; - } else { - selected_v = null; - } - } - field.singleSelect.select2('data', []); - field.singleSelect.select2(opts); - field.singleSelect.select2('data', selected_v); - field.singleSelect.prop("disabled", opts.data.length == 0); - }; - - var singleSelectChange = function () { - var v = field.singleSelectValue(); - - field.updateSubFieldUnitOpts(v); - - var curData = field.detailData || []; - var curSubField = null; - curData.forEach(function(val) { - if (val[field.id] === v) { - curSubField = val; - } - }); - - if (curSubField) { - // setvalue for subfield - field.subFieldList.forEach(function(subField) { - subField.disabled(false); - subField.setValue(curSubField[subField.id]); - }); - } else { - field.subFieldList.forEach(function(subField) { - subField.disabled(true); - subField.setValue(null); - }); - } - that.readOnlyHandler(); - }; - - setSingleSelectOptions([]); - - field.singleSelect.on("change", singleSelectChange); - - field._changeMultiFieldValue = function(added, removed) { - var newSubFieldValue = {}; - for (var subFieldName in field.data.multiplexFields) { - var subFieldId = field.data.multiplexFields[subFieldName].id; - newSubFieldValue[subFieldId] = null; - } - - var val; - if (added) { - if (added.value) { - val = added.value; - } else { - newSubFieldValue[field.id] = added.id; - val = newSubFieldValue; - } - added = { - id: added.id, - value: val - }; - } - - if (removed) { - if (removed.value){ - val = removed.value; - } else { - newSubFieldValue[field.id] = removed.id; - val = newSubFieldValue; - } - removed = { - id: removed.id, - value: val - }; - } - - var data = {}; - data[field.id] = { - multi: true, - added: added, - removed: removed - }; - that._addAllData(data); - }; - - var multiselectSetValue = field.setValue; - - // overwrite multiplex set value - field.setValue = function(v) { - // used to keep track of initially loaded multiplex data - field.detailData = v; - var multiselectValues = null; - if (v && v.length) { - multiselectValues = v.map(function(val) { - return val[field.id] - }); - } - - multiselectSetValue(multiselectValues); - var newOptions = field.input.select2('data') || []; - setSingleSelectOptions(newOptions); - singleSelectChange(); - }; - - field.disabled = function(bool) { - field.input.prop("disabled", bool); - field.subFieldList.forEach(function(subField) { - subField.disabled(bool); - }); - if (bool) { - nameContainer1.text("Select to inspect"); - } else { - nameContainer1.text("Select to edit"); - } - }; - - field.parseValue = function(value) { - var v = value; - if (v && v.length) { - v = v.map(function(opt) { - var valMap = {}; - valMap[field.id] = opt[field.id]; - for (var subFieldId in opt) { - field.subFieldList.forEach(function(subField) { - if (subField.id === subFieldId) { - valMap[subField.id] = subField.parseValue(opt[subFieldId]); - } - }); - } - return valMap; - }); - } else { - v = null; - } - return v; - }; - - field.updateSubFieldUnitOpts = function(val) { - var curOpts; - field.data.options.forEach(function(opt) { - if (opt.id === val) { - curOpts = opt; - } - }); - field.subFieldList.forEach(function(subField) { - if (subField.data.hasMultiplexUnit) { - if (curOpts && curOpts.hasOwnProperty("unitOptions")) { - subField.setUnitOpts(curOpts.unitOptions[subField.id]); - } else { - subField.setUnitOpts(null); - } - } - }) - }; - - field.multiOnChange = function(added, removed) { - field._changeMultiFieldValue(added, removed); - var v = field.getValue(); - var curData = field.detailData; - var curIds = []; - var curOpt = null; - //reshape data for saveback - if (curData) { - curIds = curData.map(function(val) { - return val[field.id] - }); - } - - var newMultiplexVal = []; - var selectList = []; - if (v) { - v.forEach(function(selectedVal) { - if (curData) { - curData.forEach(function(val) { - if (val[field.id] === selectedVal) { - newMultiplexVal.push(val) - } - }); - } - // cases when adding new data - if (curIds.indexOf(selectedVal) < 0) { - var newVal = {}; - newVal[field.id] = selectedVal; - - field.updateSubFieldUnitOpts(selectedVal); - field.subFieldList.forEach(function(subfield) { - // special handling for subfield which has multiplexUnit - if (subfield.hasUnits) { - if (subfield.data.hasMultiplexUnit) { - subfield.disabled(false); - field.data.options.forEach(function(opt) { - if (opt.id === selectedVal) { - var val = { - value: null, - unit: subfield.units[0] - }; - newVal[subfield.id] = subfield.parseValue(val); - } - }); - } else { - if (subfield.data.units) { - if (subfield.data.units.length > 1){ - subfield.disabled(false); - } - } - var val = { - value: null, - unit: subfield.defaultUnit - }; - newVal[subfield.id] = subfield.parseValue(val); - } - } - else { - newVal[subfield.id] = subfield.parseValue(null); - } - }); - newMultiplexVal.push(newVal); - } - }); - - // make data for single select options - v.forEach(function(selectId) { - field.data.options.forEach(function(opt) { - if (opt.id === selectId) { - selectList.push(opt); - } - }); - }); - // set the newest selected to be the current obj - curOpt = selectList[v.length - 1]; - } - - field.detailData = newMultiplexVal; - setSingleSelectOptions(selectList, curOpt); - singleSelectChange(); - }; - - field.getText = function(v) { - if (v === null) { - return ""; - } - // get subfields that is selected from the checkbox - if (field.id in that.globalSelectedMultiplexSubfield) { - var checkedSubfields = that.globalSelectedMultiplexSubfield[field.id]; - var returnVal = []; - for (var valIdx in v) { - var subV = v[valIdx]; - var subText = []; - for (var optId in field.data.options) { - var opt = field.data.options[optId]; - if (opt.id === subV[field.id]) { - subText.push(opt.text); - } - } - field.subFieldList.forEach(function(subField) { - if (checkedSubfields.indexOf(subField.id) >= 0) { - var x = subField.getText(subV[subField.id]); - subText.push(subField.name + ": " + x); - } - }); - returnVal.push("{" + subText.join(", ") + "}"); - } - return returnVal.join(";"); - } - }; - - field.parseText = function(v) { - if (v === null) { - return ""; - } else { - var returnVal = []; - for (var valIdx in v) { - var subV = v[valIdx]; - var subText = []; - for (var optId in field.data.options) { - var opt = field.data.options[optId]; - if (opt.id === subV[field.id]) { - subText.push(opt.text); - } - } - field.subFieldList.forEach(function(subField) { - var x = subField.getText(subV[subField.id]); - if (x) { - subText.push(x); - } - }); - returnVal.push(subText); - } - return returnVal; - } - }; - - field.checkMultiplexCompletion = function(valList) { - var valCount = 0; - var completionPct = 0; - var include = false; - function getSubfieldStatus (vals) { - var req = 0; - var fill = 0; - for (var subFieldId in field.subFieldList) { - var subField = field.subFieldList[subFieldId]; - var curVal = vals[subField.id]; - if (subField.required) { - include = true; - req++; - if (typeof(curVal) === 'object' && curVal) { - if (curVal.value) { - fill++; - } - } else if (curVal) { - fill++; - } - } - } - return fill/req; - } - - // for cases has value in multiplex field - if (valList) { - if (valList.length > 0){ - for (var idx in valList) { - valCount++; - var vals = valList[idx]; - completionPct += getSubfieldStatus(vals); - } - } else if (field.required) { - include = true; - valCount = 1; - } - } else if (field.required) { - include = true; - valCount = 1; - } - - return { - include: include, - completionPct: completionPct/valCount - }; - }; - - // valList contains all of the vals for selected val - field.applyMultiplexSubFieldColor = function(valList){ - function updateSubFieldWarningMap (vals) { - for (var subFieldId in field.subFieldList) { - var subField = field.subFieldList[subFieldId]; - // loop through each well's multiplexval list - if (vals === null){ - if (field.required && subField.required){ - subFieldWarningMap[subField.id].warningStatus.push(true); - } - } else if (typeof(vals) === "object") { - if (vals.length === 0) { - if (field.required && subField.required){ - subFieldWarningMap[subField.id].warningStatus.push(true); - } - } else { - for (var multiplexIdx in vals) { - var curVal = vals[multiplexIdx][subField.id]; - if (subField.required) { - if (typeof(curVal) === 'object' && curVal) { - if (!curVal.value) { - subFieldWarningMap[subField.id].warningStatus.push(true); - } else { - subFieldWarningMap[subField.id].warningStatus.push(false); - } - } else if (!curVal) { - subFieldWarningMap[subField.id].warningStatus.push(true); - } else { - subFieldWarningMap[subField.id].warningStatus.push(false); - } - } - } - } - } - } - } - - var subFieldWarningMap = {}; - field.subFieldList.forEach(function(subField){ - if (subField.required) { - subFieldWarningMap[subField.id] = { - field: subField, - warningStatus: [] - }; - } - }); - - valList.forEach(function(multiplexVals) { - updateSubFieldWarningMap(multiplexVals); - }); - // turn off main field when all subfield are filled - - var requiredSubField = []; - var mainFieldStatus = []; - for (var subFieldId in subFieldWarningMap){ - var subField = subFieldWarningMap[subFieldId].field; - if (subFieldWarningMap[subFieldId].warningStatus.indexOf(true) >= 0) { - var text = subField.name + " is a required subfield for " + field.name + ", please make sure all " + field.name + " have " + subField.name; - if (field.required){ - that.fieldWarningMsg(subField, text, true); - mainFieldStatus.push(true); - } else { - that.fieldWarningMsg(subField, text, true); - mainFieldStatus.push(true); - } - } else { - that.fieldWarningMsg(subField, "none", false); - mainFieldStatus.push(false); - } - } - var mainFieldWarning = false; - if (mainFieldStatus.indexOf(true) < 0) { - mainFieldWarning = false; - } else { - mainFieldWarning = true; - } - var warningText; - if (field.required) { - warningText = field.name + " is a required field, please also fix missing required subfield(s) below"; - } else { - warningText = field.name + " is not a required field, please fix missing required subfield(s) below or remove selected " + field.name; - } - that.fieldWarningMsg(field, warningText, mainFieldWarning); - }; - - field.parseMainFieldVal = function(val) { - var optMap = field.data.options; - for (var idx = 0; idx < optMap.length; idx++){ - var curOpt = optMap[idx]; - if (curOpt.id === val){ - return curOpt.text - } - } - }; - }, - - _deleteDialog: function (field) { - var that = this; - - var valMap = field.allSelectedMultipleVal; - var valToRemove; - if (valMap) { - valToRemove = Object.keys(valMap); - } else { - valToRemove = []; - } - - - var dialogDiv = $("<div/>").addClass("delete-dialog modal"); - $('body').append(dialogDiv); - - function killDialog() { - dialogDiv.hide(); - dialogDiv.remove(); - } - - var dialogContent = $("<div/>").addClass("modal-content").appendTo(dialogDiv); - var tableArea = $("<div/>").appendTo(dialogContent); - var buttonRow = $("<div/>").addClass("dialog-buttons").css("justify-content", "flex-end").appendTo(dialogContent); - - if (valToRemove.length > 0){ - // apply CSS property for table - $("<p/>").text(field.name + " in selected wells: choose items to delete and click the delete button below").appendTo(tableArea); - - var table = that._deleteDialogTable(field, valMap); - table.appendTo(tableArea); - table.addClass("plate-popout-table"); - table.find('td').addClass("plate-popout-td"); - table.find('th').addClass("plate-popout-th"); - table.find('tr').addClass("plate-popout-tr"); - if (!that.readOnly) { - var deleteCheckedButton = $("<button class='multiple-field-manage-delete-button'>Delete Checked Items</button>"); - buttonRow.append(deleteCheckedButton); - deleteCheckedButton.click(function() { - table.find("input:checked").each(function () { - var val = this.value; - field.multiOnChange(null, {id: val}); - }); - // refresh selected fields after updating the multiplex field value - that.decideSelectedFields(); - killDialog(); - }); - } - - } else { - $("<p/>").text("No " + field.name + " in the selected wells").appendTo(tableArea); - } - - var cancelButton = $("<button>Cancel</button>"); - buttonRow.append(cancelButton); - cancelButton.click(killDialog); - - dialogDiv.show(); - - window.onclick = function(event) { - if (event.target == dialogDiv[0]) { - killDialog(); - } - } - }, - - _deleteDialogTable: function (field, valMap) { - var that = this; - var colName = [field.name, "Counts"]; //Added because it was missing... no idea what the original should have been - if (!that.readOnly) { - colName.push("Delete"); - } - var table = $('<table/>'); - var thead = $('<thead/>').appendTo(table); - var tr = $('<tr/>').appendTo(thead); - - tr.append(colName.map(function (text) { - return $('<th/>').text(text); - })); - - var tbody = $("<tbody/>").appendTo(table); - - field.data.options.forEach(function (opt) { - if (opt.id in valMap) { - var tr = $('<tr/>').appendTo(tbody); - var checkbox = $("<input type='checkbox'>").prop("value", opt.id); - $("<td/>").text(opt.text).appendTo(tr); - $("<td/>").text(valMap[opt.id]).appendTo(tr); - if (!that.readOnly) { - $("<td/>").append(checkbox).appendTo(tr); - } - } - }); - - return table; - }, - - _createDeleteButton: function (field) { - var that = this; - var deleteButton = $("<button/>").addClass("plate-setup-remove-all-button"); - deleteButton.id = field.id + "Delete"; - deleteButton.text("Manage " + field.name + "..."); - var buttonContainer = that._createElement("<div></div>").addClass("plate-setup-remove-all-button-container"); - buttonContainer.append(deleteButton); - - field.deleteButton = deleteButton; - field.root.find(".plate-setup-tab-field-right-side").append(buttonContainer); - - deleteButton.click(function () { - that._deleteDialog(field); - }); - } - - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.engine = function(THIS) { - // Methods which look after data changes and stack up accordingly - // Remember THIS points to plateLayOutWidget and 'this' points to engine - // Use THIS to refer parent this. - return { - engine: { - - derivative: {}, - stackUpWithColor: {}, - stackPointer: 2, - - wellEmpty: function (well) { - for (var prop in well) { - var curVal = well[prop]; - if (curVal !== null && curVal !== undefined) { - if (Array.isArray(curVal)) { - if (curVal.length > 0) { - return false; - } - } else { - return false; - } - } - } - return true; - }, - - searchAndStack: function() { - // This method search and stack the change we made. - this.stackUpWithColor = {}; - this.stackPointer = 1; - var derivativeJson = {}; - for (var idx in this.derivative) { - var data = this.derivative[idx]; - var wellData = {}; - for (var i = 0; i < THIS.globalSelectedAttributes.length; i++) { - var attr = THIS.globalSelectedAttributes[i]; - - if (attr in THIS.globalSelectedMultiplexSubfield){ - var selectedSubFields = THIS.globalSelectedMultiplexSubfield[attr]; - var newMultiplexVal = []; - for (var multiplexIdx in data[attr]){ - var curMultiplexVals = data[attr][multiplexIdx]; - var newVal = {}; - newVal[attr] = curMultiplexVals[attr]; - selectedSubFields.forEach(function (subFieldId) { - newVal[subFieldId] = curMultiplexVals[subFieldId]; - }); - newMultiplexVal.push(newVal); - } - wellData[attr] = newMultiplexVal; - } else { - if (data[attr] != null) { - wellData[attr] = data[attr]; - } - } - } - if ($.isEmptyObject(wellData)) { - derivativeJson[idx] = null; - } else { - derivativeJson[idx] = JSON.stringify(wellData); - } - } - - while (!$.isEmptyObject(derivativeJson)) { - var keys = Object.keys(derivativeJson).map(function (k) {return parseFloat(k, 10);}); - keys.sort(function (a, b) {return a-b;}); - - var refDerivativeIndex = keys[0]; - var referenceDerivative = derivativeJson[refDerivativeIndex]; - var arr = []; - - if (!referenceDerivative) { - // if no checked box has value, push it to first spot - if (this.stackUpWithColor[0]) { - this.stackUpWithColor[0].push(refDerivativeIndex); - } else { - this.stackUpWithColor[0] = [refDerivativeIndex]; - } - - delete derivativeJson[refDerivativeIndex]; - } else { - // if checked boxes have values - for (var i = 0; i < keys.length; i++) { - var idx = keys[i]; - if (referenceDerivative == derivativeJson[idx]) { - arr.push(idx); - this.stackUpWithColor[this.stackPointer] = arr; - delete derivativeJson[idx]; - } - } - if (arr.length > 0) - this.stackPointer++; - } - } - }, - - applyColors: function() { - - var wholeNoTiles = 0; - var wholePercentage = 0; - - THIS.addBottomTableHeadings(); - - for (var i = 0; i < THIS.allTiles.length; i++) { - var tile = THIS.allTiles[i]; - THIS.setTileVisible(tile, false); - } - - for (var color = 0; color < this.stackPointer; color++) { - var arr = this.stackUpWithColor[color]; - if (arr) { - THIS.addBottomTableRow(color, arr); - - for (var tileIndex in arr) { - wholeNoTiles++; - var index = this.stackUpWithColor[color][tileIndex]; - var tile = THIS.allTiles[index]; - var well = this.derivative[index]; - THIS.setTileColor(tile, color, this.stackPointer); - // Checks if all the required fields are filled - var completion = this.checkCompletion(well, tile); - THIS.setTileComplete(tile, completion == 1); - wholePercentage = wholePercentage + completion; - } - } - } - - wholePercentage = Math.floor(100 * wholePercentage / wholeNoTiles); - - if (isNaN(wholePercentage)) { - THIS.overLayTextContainer.text("Completion Percentage: 0%"); - } else { - THIS.overLayTextContainer.text("Completion Percentage: " + wholePercentage + "%"); - } - }, - - checkCompletion: function(wellData, tile) { - var req = 0; - var fill = 0; - for (var i = 0; i < THIS.fieldList.length; i++) { - var field = THIS.fieldList[i]; - if (field.checkMultiplexCompletion){ - // also apply color - var multiplexStatus = field.checkMultiplexCompletion(wellData[field.id]); - if (multiplexStatus.include) { - fill += multiplexStatus.completionPct; - req++; - } - } else { - if (field.required) { - req++; - if (wellData[field.id] !== null) { - fill++; - } - } - } - } - if (req === fill) { - return 1; - } - return fill / req; - }, - } - } - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.fabricEvents = function() { - // This object contains Menu items and how it works; - return { - colorToIndex: {}, - startCoords: { - x: 0, - y: 0 - }, - focalWell: { - row: 0, - col: 0 - }, - selectedAreas: [], - - _clickCoords: function(evt) { - //Get XY Coords for a given event. - var rect = evt.e.target.getBoundingClientRect(); - return { - x: evt.e.clientX - rect.left, - y: evt.e.clientY - rect.top - }; - }, - - _fabricEvents: function() { - // Set up event handling. - var that = this; - - $(that.target).on("getPlates", function(evt, data) { - // This method should be compatable to redo/undo. - that.getPlates(JSON.parse(data)); - }); - - that.mainFabricCanvas.on("mouse:down", function(evt) { - // Start selecting new area - that.selecting = true; - var coords = that._clickCoords(evt); - - var areas = that.selectedAreas.slice(); - var focalWell = that.focalWell; - var startCoords = that._wellToCoords(focalWell, true); - var rect = that._coordsToRect(startCoords, coords); - - if (evt.e.ctrlKey) { - //adding new area - startCoords = coords; - rect = that._coordsToRect(startCoords, coords); - focalWell = that._coordsToWell(startCoords); - if (evt.e.shiftKey) { - //replacing existing areas - areas = [that._rectToArea(rect)]; - } else { - areas.push(that._rectToArea(rect)); - } - } else { - if (evt.e.shiftKey) { - //Altering last area - areas[areas.length - 1] = that._rectToArea(rect); - } else { - //Creating new area - startCoords = coords; - rect = that._coordsToRect(startCoords, coords); - focalWell = that._coordsToWell(startCoords); - areas = [that._rectToArea(rect)]; - } - } - - that.startCoords = startCoords; - that.setSelection(areas, focalWell); - that.mainFabricCanvas.renderAll(); - }); - - that.mainFabricCanvas.on("mouse:move", function(evt) { - if (that.selecting) { - // continue selecting new area - var areas = that.selectedAreas.slice(); - var endCoords = that._clickCoords(evt); - var rect = that._coordsToRect(that.startCoords, endCoords); - var area = that._rectToArea(rect); - if (area) { - areas[areas.length - 1] = area; - } - - that.setSelection(areas, that.focalWell); - that.mainFabricCanvas.renderAll(); - } - - }); - - that.mainFabricCanvas.on("mouse:up", function(evt) { - // finish selecting new area - that.selecting = false; - var areas = that.selectedAreas.slice(); - var endCoords = that._clickCoords(evt); - var rect = that._coordsToRect(that.startCoords, endCoords); - var area = that._rectToArea(rect); - if (area) { - areas[areas.length - 1] = area; - } - - that.setSelection(areas, that.focalWell); - that.decideSelectedFields(); - that.mainFabricCanvas.renderAll(); - that._trigger("selectedWells", null, {selectedAddress: that.getSelectedAddress()}); - }); - }, - - setSelection: function(areas, focalWell) { - this.selectedAreas = areas; - this.focalWell = focalWell; - this.allSelectedObjects = this._areasToTiles(areas); - this._setSelectedTiles(); - this._setFocalWellRect(this.focalWell); - document.activeElement.blur(); - }, - - _setFocalWellRect: function(well) { - var flag; - // check if not allow to add or delete existing wells - if (this.disableAddDeleteWell) { - var address = this.locToAddress({ - r: well.row, - c: well.col - }); - if (this.addressAllowToEdit.indexOf(address) < 0) { - flag = false; - this.setFieldsDisabled(true); - } else { - flag = true; - this.setFieldsDisabled(false); - } - } else if (well) { - flag = true; - } - - if (flag) { - var rect = this._areaToRect(this._wellToArea(well)); - var strokeWidth = 2; - if (this.focalWellRect) { - //update focalWellRect - this.focalWellRect.top = rect.top; - this.focalWellRect.left = rect.left; - this.focalWellRect.width = rect.width - strokeWidth; - this.focalWellRect.height = rect.height - strokeWidth; - } else { - //create focalWellRect - this.focalWellRect = new fabric.Rect({ - width: rect.width - strokeWidth, - height: rect.height - strokeWidth, - left: rect.left, - top: rect.top, - fill: null, - strokeWidth: strokeWidth, - stroke: "black", - selectable: false - }); - this.mainFabricCanvas.add(this.focalWellRect); - } - } else { - //clear focalWellRect - this.mainFabricCanvas.remove(this.focalWellRect); - this.focalWellRect = null; - } - }, - - _setSelectedTiles: function() { - // Update selected tile display only - var selectedTiles = this.allSelectedObjects; - this.allTiles.forEach(function(tile) { - var selected = selectedTiles.indexOf(tile) >= 0; - tile.highlight.visible = selected; - }) - }, - - _getSelectedWells: function () { - var that = this; - return this.allSelectedObjects.map(function (tile) { - var well = that.engine.derivative[tile.index]; - if (!well) { - well = that.defaultWell; - } - return well; - }); - }, - - _getCommonFields: function (wells) { - if (wells.length) { - var referenceWell = wells[0]; - var referenceFields = $.extend(true, {}, referenceWell); - for (var i = 1; i < wells.length; i++) { - var fields = wells[i]; - for (var field in referenceFields) { - if (Array.isArray(referenceFields[field])) { - var refArr = referenceFields[field]; - var agrArr = []; - for (var j = 0; j < refArr.length; j++) { - var v = refArr[j]; - if (v && typeof(v) === "object") { - if (this.containsObject(v, fields[field])) { - agrArr.push(v); - } - } else { - if ($.inArray(v, fields[field]) >= 0) { - agrArr.push(v); - } - } - } - referenceFields[field] = agrArr; - } else { - if (fields[field] && typeof(fields[field]) ==="object" && referenceFields[field] && typeof(referenceFields[field]) ==="object"){ - if ((fields[field].value !== referenceFields[field].value) || (fields[field].unit !== referenceFields[field].unit)){ - delete referenceFields[field]; - } - } else if (referenceFields[field] != fields[field]) { - delete referenceFields[field]; - } - } - } - } - return referenceFields - } else { - return {}; - } - }, - - containsObject: function(obj, list) { - var equality = []; - if (list) { - list.forEach(function(val) { - //evaluate val and obj - var evaluate = []; - Object.keys(val).forEach(function(listKey){ - if (Object.keys(obj).indexOf(listKey) >= 0){ - var curVal = val[listKey]; - if (typeof(curVal) === 'object' && curVal) { - if (obj[listKey]){ - evaluate.push((curVal.unit === obj[listKey].unit) && (curVal.value === obj[listKey].value)); - } else { - // when obj[listKey] is null but curVal is not - evaluate.push(false); - } - } else { - evaluate.push(curVal === obj[listKey]); - } - } - }); - equality.push(evaluate.indexOf(false) < 0); - }); - return equality.indexOf(true) >= 0; - } else { - return false; - } - }, - - _getCommonWell: function (wells) { - if (wells.length) { - var referenceWell = wells[0]; - var referenceFields = $.extend(true, {}, referenceWell); - for (var i = 1; i < wells.length; i++) { - var well = wells[i]; - var fields = well; - for (var field in referenceFields) { - if (Array.isArray(referenceFields[field])) { - var refArr = referenceFields[field]; - var agrArr = []; - for (var j = 0; j < refArr.length; j++) { - var v = refArr[j]; - // for multiplex field - if (typeof(refArr[j]) ==="object"){ - if (this.containsObject(v, fields[field])) { - agrArr.push(v); - } - } else { - if ($.inArray(v, fields[field]) >= 0) { - agrArr.push(v); - } - } - } - referenceFields[field] = agrArr; - } else { - if (fields[field] && typeof(fields[field]) ==="object" && referenceFields[field] && typeof(referenceFields[field]) ==="object"){ - if ((fields[field].value !== referenceFields[field].value) || (fields[field].unit !== referenceFields[field].unit)){ - referenceFields[field] = null; - } - } else if (referenceFields[field] != fields[field]) { - referenceFields[field] = null; - } - - } - } - } - return referenceFields; - } else { - return this.defaultWell; - } - }, - - _getAllMultipleVal: function (wells) { - var multipleFieldList = this.multipleFieldList; - - multipleFieldList.forEach(function(multiplexField) { - if(wells.length) { - var curMultipleVal = {}; - wells.forEach(function (wellData) { - var id = multiplexField.id; - if (wellData[id]){ - if (wellData[id].length > 0) { - wellData[id].forEach(function (multipleVal) { - if (typeof(multipleVal) === 'object') { - if (multipleVal[id] in curMultipleVal) { - curMultipleVal[multipleVal[id]] ++; - } else { - curMultipleVal[multipleVal[id]] = 1; - } - } else { - if (multipleVal in curMultipleVal) { - curMultipleVal[multipleVal] ++; - - } else { - curMultipleVal[multipleVal] = 1; - } - } - }) - } - } - }); - multiplexField.allSelectedMultipleVal = curMultipleVal; - } else { - multiplexField.allSelectedMultipleVal = null - } - }); - }, - - decideSelectedFields: function() { - var wells = this._getSelectedWells(); - this._getAllMultipleVal(wells); - this.applyFieldWarning(wells); - var well = this._getCommonWell(wells); - this._addDataToTabFields(well); - }, - - // get well value differences for each well in wellsHash - getDifferentWellsVals: function(wellsHash) { - var wells = []; - for (var wellId in wellsHash){ - wells.push(wellsHash[wellId]); - } - var differentWellsVals = {}; - if (wells.length > 1){ - var commonWell = this._getCommonWell(wells); - var allFieldVal = {}; - for (var fieldIdx in wellsHash[0]) { - allFieldVal[fieldIdx] = []; - } - for (var wellIdx in wells){ - var diffWellVal = {}; - var curWellData = wells[wellIdx]; - for (var fieldId in curWellData) { - var commonVal = commonWell[fieldId]; - var curVal = curWellData[fieldId]; - var newVal = null; - if (Array.isArray(curVal)) { - // get uncommonVal - newVal = []; - for (var idx = 0; idx < curVal.length; idx ++){ - var curMultiVal = curVal[idx]; - // multiplex field - if (curMultiVal && typeof(curMultiVal === "object")){ - if (!this.containsObject(curMultiVal, commonVal)) { - newVal.push(curMultiVal); - if (!this.containsObject(curMultiVal, allFieldVal[fieldId])) { - allFieldVal[fieldId].push(curMultiVal); - } - } - } else { - if (commonVal.indexOf(curMultiVal) >= 0) { - newVal.push(curMultiVal); - if (!allFieldVal[fieldId].indexOf(curMultiVal) >= 0) { - allFieldVal[fieldId].push(curMultiVal); - } - } - } - } - } else if (curVal && typeof(curVal) === "object"){ - if (commonVal && typeof(commonVal) ==="object"){ - if (!((curVal.value === commonVal.value) || (curVal.unit === commonVal.unit))){ - newVal = curVal; - if (!this.containsObject(curVal, allFieldVal[fieldId])) { - allFieldVal[fieldId].push(curVal); - } - } - } else { - newVal = curVal; - if (!this.containsObject(curVal, allFieldVal[fieldId])) { - allFieldVal[fieldId].push(curVal); - } - } - } else if (curVal !== commonVal) { - newVal = curVal; - if (!allFieldVal[fieldId].indexOf(curVal) >= 0) { - allFieldVal[fieldId].push(curVal); - } - } - diffWellVal[fieldId] = newVal; - } - - - differentWellsVals[wellIdx] = diffWellVal; - } - - // clean up step for fields that are empty - for (var fieldId in allFieldVal) { - if (allFieldVal[fieldId].length === 0) { - for (var wellIdx in differentWellsVals){ - delete differentWellsVals[wellIdx][fieldId]; - } - } - } - - return differentWellsVals; - } else if (wellsHash[0]) { - var well = {}; - for (var fieldId in wellsHash[0]) { - var curVal = wellsHash[0][fieldId]; - if (Array.isArray(curVal)){ - if (curVal.length > 0) { - well[fieldId] = curVal - } - } else if (curVal){ - well[fieldId] = curVal; - } - } - return { - 0: well - }; - } - }, - - // get all wells that has data - getWellSetAddressWithData: function(){ - var address = []; - var derivative = this.engine.derivative; - for (var id in derivative){ - address.push(this.indexToAddress(id)); - } - return address; - } - - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -plateLayOutWidget.assets = function () { - return { - _assets: { - doImg: '✓', - dontImg: '', - warningImg: '⚠' - } - }; -}; - -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.interface = function() { - // interface holds all the methods to put the interface in place - return { - - _createInterface: function() { - - var divIdentifier = '<div></div>'; - this.container = this._createElement(divIdentifier).addClass("plate-setup-wrapper"); - this.topSection = this._createElement(divIdentifier).addClass("plate-setup-top-section"); - - this.topLeft = this._createElement(divIdentifier).addClass("plate-setup-top-left"); - this.topRight = this._createElement(divIdentifier).addClass("plate-setup-top-right"); - - this.overLayContainer = this._createElement(divIdentifier).addClass("plate-setup-overlay-container"); - this.canvasContainer = this._createElement(divIdentifier).addClass("plate-setup-canvas-container"); - - this._createOverLay(); - $(this.topLeft).append(this.overLayContainer); - - this._createCanvas(); - $(this.topLeft).append(this.canvasContainer); - - - $(this.topSection).append(this.topLeft); - $(this.topSection).append(this.topRight); - - $(this.container).append(this.topSection); - $(this.element).append(this.container); - - this._initiateFabricCanvas(); - - this._createTabAtRight(); - this._createTabs(); - - this._placePresetTabs(); - // Bottom of the screen - this._bottomScreen(); - // Canvas - this._canvas(); - - this.bottomForFirstTime(); - - var that = this; - this._setShortcuts(); - $(document.body).keyup(function(e) { - that._handleShortcuts(e); - }); - - this._configureUndoRedoArray(); - }, - - _createElement: function(element) { - return $(element); - }, - - _setShortcuts: function () { - var that = this; - window.addEventListener("cut", function (e) { - if (document.activeElement == document.body) { - that.copyCriteria(); - that.clearCriteria(); - e.preventDefault(); - } - }); - window.addEventListener("copy", function (e) { - if (document.activeElement == document.body) { - that.copyCriteria(); - e.preventDefault(); - } - }); - window.addEventListener("paste", function (e) { - if (document.activeElement == document.body) { - that.pasteCriteria(); - e.preventDefault(); - } - }); - }, - - _handleShortcuts: function(e) { - if (document.activeElement === document.body) { - if (e.keyCode == 46) { - this.clearCriteria(); - e.preventDefault(); - } else if (e.ctrlKey || e.metaKey) { - if (e.keyCode == 90) { - if (e.shiftKey) { - this.redo(); - } else { - this.undo(); - } - e.preventDefault(); - } else if (e.keyCode == 89) { - this.redo(); - e.preventDefault(); - } - } - } - }, - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.loadPlate = function(THIS) { - // Methods which look after data changes and stack up accordingly - // Remember THIS points to plateLayOutWidget and 'this' points to engine - return { - - getPlates: function (data) { - //sanitize input - var derivative = {}; - for (var index in data.derivative) { - var well = data.derivative[index]; - derivative[index] = this.sanitizeWell(well); - } - - var checkboxes = data.checkboxes || []; - var selection = this.sanitizeAreas(data.selectedAreas, data.focalWell); - - var sanitized = { - "derivative": derivative, - "checkboxes": checkboxes, - "selectedAreas": selection.selectedAreas, - "focalWell": selection.focalWell - }; - - this.setData(sanitized); - }, - - sanitizeAreas: function (selectedAreas, focalWell) { - var that = this; - var rows = this.dimensions.rows; - var cols = this.dimensions.cols; - - if (!selectedAreas) { - selectedAreas = []; - } - if (selectedAreas.length) { - selectedAreas = selectedAreas.map(function (area) { - return { - minCol: that._coordIndex(Math.min(area.minCol, area.maxCol), cols), - minRow: that._coordIndex(Math.min(area.minRow, area.maxRow), rows), - maxCol: that._coordIndex(Math.max(area.minCol, area.maxCol), cols), - maxRow: that._coordIndex(Math.max(area.minRow, area.maxRow), rows) - }; - }); - var area = selectedAreas[selectedAreas.length - 1]; - if (focalWell && !this._wellInArea(focalWell, area)) { - focalWell = null; - } - if (!focalWell) { - focalWell = { - row: area.minRow, - col: area.minCol - }; - } - } else { - if (!focalWell) { - focalWell = { - row: 0, - col: 0 - }; - } - selectedAreas = [this._wellToArea(focalWell)]; - } - return { - selectedAreas: selectedAreas, - focalWell: focalWell - }; - }, - - sanitizeWell: function (well) { - var newWell = {}; - for (var i = 0; i < this.fieldList.length; i++) { - var field = this.fieldList[i]; - newWell[field.id] = field.parseValue(well[field.id]); - } - return newWell; - }, - - setData: function(data) { - this.engine.derivative = $.extend(true, {}, data.derivative); - this.setCheckboxes(data.checkboxes); - this.setSelection(data.selectedAreas, data.focalWell); - this._colorMixer(); - this.decideSelectedFields(); - this.mainFabricCanvas.renderAll(); - }, - - } - } -})(jQuery, fabric); -var GET_PLATES = 'getPlates'; -var IS_READ_ONLY = 'isReadOnly'; -var IS_DISABLE_ADD_DELETE_WELL = 'isDisableAddDeleteWell'; -var GET_SELECTED_OBJECT = 'getSelectedObject'; -var SETSELECTEDWELL = 'setSelectedWell'; -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.overlay = function() { - // overlay holds all the methods to put the part just above the canvas which contains all those - // 'completion percentage' annd 'copy Criteria' button etc ... - return { - - _createOverLay: function() { - - var that = this; - this.overLayTextContainer = this._createElement("<div></div>").addClass("plate-setup-overlay-text-container"); - this.overLayTextContainer.text("Completion Percentage:"); - this.overLayContainer.append(this.overLayTextContainer); - this.overLayButtonContainer = this._createElement("<div></div>").addClass("plate-setup-overlay-button-container"); - this.overLayContainer.append(this.overLayButtonContainer); - - this.clearCriteriaButton = this._createElement("<button />").addClass("plate-setup-button"); - this.clearCriteriaButton.text("Clear"); - this.overLayButtonContainer.append(this.clearCriteriaButton); - - this.clearCriteriaButton.click(function(evt) { - that.clearCriteria(); - }); - - this.copyCriteriaButton = this._createElement("<button />").addClass("plate-setup-button"); - this.copyCriteriaButton.text("Copy"); - this.overLayButtonContainer.append(this.copyCriteriaButton); - - this.copyCriteriaButton.click(function(evt) { - that.copyCriteria(); - }); - - this.pasteCriteriaButton = this._createElement("<button />").addClass("plate-setup-button"); - this.pasteCriteriaButton.text("Paste"); - this.overLayButtonContainer.append(this.pasteCriteriaButton); - - this.pasteCriteriaButton.click(function(evt) { - that.pasteCriteria(); - }); - - this.undoButton = this._createElement("<button />").addClass("plate-setup-button"); - this.undoButton.text("Undo"); - this.overLayButtonContainer.append(this.undoButton); - - this.undoButton.click(function(evt) { - that.undo(); - }); - - this.redoButton = this._createElement("<button />").addClass("plate-setup-button"); - this.redoButton.text("Redo"); - this.overLayButtonContainer.append(this.redoButton); - - this.redoButton.click(function(evt) { - that.redo(); - }); - - }, - - clearCriteria: function() { - if (this.allSelectedObjects) { - var noOfSelectedObjects = this.allSelectedObjects.length; - var hasWellUpdate = false; - for (var objectIndex = 0; objectIndex < noOfSelectedObjects; objectIndex++) { - var tile = this.allSelectedObjects[objectIndex]; - if (tile.index in this.engine.derivative) { - // handling for clearing well when not allowed to add or delete wells - if (this.emptyWellWithDefaultVal && this.disableAddDeleteWell) { - var well = JSON.parse(JSON.stringify(this.defaultWell)); - var defaultValue = this.emptyWellWithDefaultVal; - for (var key in defaultValue){ - if (key in well) { - well[key] = defaultValue[key]; - this._applyFieldData(key, defaultValue[key]); - } else { - console.log("Well does not contain key: " + key + ", please contact support"); - } - } - this.engine.derivative[tile.index] = well; - } else { - delete this.engine.derivative[tile.index]; - } - hasWellUpdate = true; - } - } - if (hasWellUpdate){ - this.derivativeChange(); - } - - this._colorMixer(); - this.decideSelectedFields(); - } else { - alert("Please select any well"); - } - }, - - copyCriteria: function() { - if (this.allSelectedObjects) { - var wells = this._getSelectedWells(); - this.commonWell = this._getCommonFields(wells); - } else { - alert("Please select any well."); - } - }, - - pasteCriteria: function() { - if (this.commonWell) { - this._addAllData(this.commonWell); - this.decideSelectedFields(); - this.mainFabricCanvas.renderAll(); - } - } - }; - } -})(jQuery, fabric); -$.widget("DNA.plateLayOut", { - - plateLayOutWidget: {}, - - options: { - value: 0 - }, - - allTiles: [], // All tiles containes all thise circles in the canvas - - addressToLoc: function (layoutAddress) { - var m = /^([A-Z]+)(\d+)$/.exec(layoutAddress.trim().toUpperCase()) - if (m) { - var row_v = m[1]; - var col = parseInt(m[2])-1; - var row; - for (var i = 0; i < row_v.length; i++) { - var c = row_v.charCodeAt(i) - 65; - if (i) { - row += 1; - row *= 26; - row += c ; - } else { - row = c; - } - } - return { - r: row, - c: col - }; - } else { - throw layoutAddress + " not a proper layout address"; - } - }, - - locToIndex: function (loc, dimensions) { - if (!dimensions) { - dimensions = this.dimensions; - } - if (loc.r < 0) { - t - } - if (!(loc.r >= 0 && loc.r < dimensions.rows)) { - throw "Row index " + (loc.r + 1) + " invalid"; - } - if (!(loc.c >= 0 && loc.c < dimensions.cols)) { - throw "Column index " + (loc.c + 1) + " invalid"; - } - return loc.r*dimensions.cols + loc.c; - }, - - addressToIndex: function (layoutAddress, dimensions) { - var loc = this.addressToLoc(layoutAddress); - return this.locToIndex(loc, dimensions); - }, - - _rowKey: function (i) { - var c1 = i % 26; - var c2 = (i - c1) / 26; - var code = String.fromCharCode(65 + c1); - if (c2 > 0) { - code = String.fromCharCode(64 + c2) + code; - } - return code; - }, - - indexToLoc: function (index, dimensions) { - if (!dimensions) { - dimensions = this.dimensions; - } - - if (index >= dimensions.rows * dimensions.cols) { - throw "Index too high: " + index.toString(10); - } - var loc = {}; - loc.c = index % dimensions.cols; - loc.r = (index - loc.c) / dimensions.cols; - - return loc; - }, - - locToAddress: function (loc) { - return this._rowKey(loc.r) + (loc.c + 1).toString(10); - }, - - indexToAddress: function (index, dimensions) { - var loc = this.indexToLoc(index, dimensions); - return this.locToAddress(loc); - }, - - getDimensions: function () { - return $.extend(true, {}, this.dimensions); - }, - - _create: function() { - var rows = parseInt(this.options.numRows || 8); - var cols = parseInt(this.options.numCols || 12); - this.dimensions = { - rows: rows, - cols: cols - }; - this.rowIndex = []; - for (var i = 0; i < rows; i++) { - this.rowIndex.push(this._rowKey(i)); - } - - this.target = (this.element[0].id) ? "#" + this.element[0].id : "." + this.element[0].className; - - // Import classes from other files.. Here we import it using extend and add it to this - // object. internally we add to widget.DNA.getPlates.prototype. - // Helpers are methods which return other methods and objects. - // add Objects to plateLayOutWidget and it will be added to this object. - // set read only well - if (this.options.readOnly){ - this.isReadOnly(true); - } - - for (var component in plateLayOutWidget) { - // Incase some properties has to initialize with data from options hash, - // we provide it sending this object. - $.extend(this, new plateLayOutWidget[component](this)); - } - - this.imgSrc = this.options.imgSrc || "assets"; - - this._createInterface(); - - this._trigger("created", null, this); - - return this; - }, - - _init: function() { - // This is invoked when the user use the plugin after _create is called. - // The point is _create is invoked for the very first time and for all other - // times _init is used. - }, - - addData: function() { - alert("wow this is good"); - }, - - // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}} - getTextDerivative: function(wellsData) { - var textDerivative = {}; - var fieldMap = this.fieldMap; - for (var idx in wellsData){ - var textValWell = {}; - var textFieldIdWell = {}; - var curWellData = wellsData[idx]; - for (var fieldId in curWellData){ - if (fieldId in this.fieldMap){ - var field = this.fieldMap[fieldId]; - var textVal = field.parseText(curWellData[fieldId]); - textFieldIdWell[field.name] = textVal; - textValWell[fieldId] = textVal; - } else { - // do not convert if not a field (ex: layout_address) - textFieldIdWell[fieldId] = curWellData[fieldId]; - textValWell[fieldId] = curWellData[fieldId]; - } - } - textDerivative[idx] = { - textVal: textValWell, - textFieldVal: textFieldIdWell - }; - } - - return textDerivative; - }, - - // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}} - getWellsDifferences: function(wellsData) { - return this.getDifferentWellsVals(wellsData); - }, - - setFieldsDisabled: function(flag){ - this.fieldList.forEach(function(field){ - field.disabled(flag); - }); - }, - - isReadOnly: function(flag){ - if (flag){ - this.readOnly = true; - } else { - this.readOnly = false; - } - this.readOnlyHandler(); - }, - - readOnlyHandler: function(){ - if (this.readOnly){ - this.overLayButtonContainer.css("display", "none"); - $('.multiple-field-manage-delete-button').css("display", "none"); - this.setFieldsDisabled(true); - } else { - this.overLayButtonContainer.css("display", "flex"); - $('.multiple-field-manage-delete-button').css("display", "none"); - if (!this.disableAddDeleteWell) { - this.setFieldsDisabled(false); - } - } - }, - - disableAddDeleteWell: null, - // column_with_default_val will be used to determine empty wells, format: {field_name: default_val} - isDisableAddDeleteWell: function(flag, column_with_default_val){ - if (flag){ - this.disableAddDeleteWell = true; - this.addressAllowToEdit = this.getWellSetAddressWithData(); - // configure undo redo action - this.actionPointer = 0; - this.undoRedoArray = []; - this.undoRedoArray.push(this.createObject()); - if (column_with_default_val) { - this.emptyWellWithDefaultVal = column_with_default_val; - } - } else { - this.disableAddDeleteWell = false; - this.setFieldsDisabled(false); - this.emptyWellWithDefaultVal = null; - } - this._fabricEvents(); - }, - - getSelectedObject: function() { - var selectedAddress = []; - for (var i = 0; i < this.allSelectedObjects.length; i++){ - selectedAddress.push(this.allSelectedObjects[i].address); - } - var selectedObjects = {}; - var derivative = this.engine.derivative; - for (var loc in derivative){ - var address = this.indexToAddress(loc); - if (selectedAddress.indexOf(address) >= 0) { - selectedObjects[address] = derivative[loc]; - } - } - return selectedObjects; - }, - - getSelectedIndex: function() { - return this.allSelectedObjects.map(function(selectedObj){ - return that.addressToIndex(selectedObj.address) - }); - }, - - getSelectedAddress: function() { - return this.allSelectedObjects.map(function(selectedObj){ - return selectedObj.address; - }); - }, - - setSelectedWell: function(addressList) { - var areas = []; - var minRow = 999; - var locMap = {}; - for (var id = 0; id < addressList.length; id++){ - var wellIdx = this.addressToIndex(addressList[id]); - var loc = this.indexToLoc(wellIdx); - areas.push({ - minCol: loc.c, - minRow: loc.r, - maxCol: loc.c, - maxRow: loc.r - }); - if (loc.r <= minRow) { - minRow = loc.r; - if (loc.r in locMap) { - locMap[loc.r].push(loc.c); - } else { - locMap[loc.r] = [loc.c]; - } - } - } - var focalWell = { - row: minRow, - col: Math.min.apply(null, locMap[minRow]) - }; - - this.setSelection(areas, focalWell); - this.decideSelectedFields(); - this.mainFabricCanvas.renderAll(); - } - -}); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.preset = function(me) { - // All the preset action goes here - return { - - presets: [], - - _placePresetTabs: function() { - var presets = this.options.attributes.presets; - - if (presets && presets.length) { - this.wellAttrContainer = this._createElement("<div></div>").addClass("plate-setup-well-attr-container") - .text("Checkbox presets"); - this.tabContainer.append(this.wellAttrContainer); - - this.presetTabContainer = this._createElement("<div></div>").addClass("plate-setup-preset-container"); - this.tabContainer.append(this.presetTabContainer); - - for (var i = 0; i < presets.length; i++) { - var preset = presets[i]; - var divText = this._createElement("<div></div>").addClass("plate-setup-prest-tab-div") - .text(preset.title); - - var presetButton = this._createElement("<div></div>").addClass("plate-setup-prest-tab") - .data("preset", preset.fields).append(divText); - this.presetTabContainer.append(presetButton); - - var that = this; - presetButton.click(function() { - var preset = $(this); - that._selectPreset(preset); - }); - this.presets.push(presetButton); - } - } - }, - - _clearPresetSelection: function() { - for (var j = 0; j < this.presets.length; j++) { - var p = this.presets[j]; - p.removeClass("plate-setup-prest-tab-selected") - .addClass("plate-setup-prest-tab"); - } - }, - - _selectPreset: function (preset) { - this.setCheckboxes(preset.data("preset")); - preset.removeClass("plate-setup-prest-tab") - .addClass("plate-setup-prest-tab-selected"); - }, - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.tabs = function() { - // Tabs crete and manage tabs at the right side of the canvas. - return { - - allTabs: [], - - defaultWell: {}, - - allDataTabs: [], // To hold all the tab contents. this contains all the tabs and its elements and elements - // Settings as a whole. its very usefull, when we have units for a specific field. - // it goes like tabs-> individual field-> units and checkbox - - _createTabAtRight: function() { - this.tabContainer = this._createElement("<div></div>").addClass("plate-setup-tab-container"); - $(this.topRight).append(this.tabContainer); - }, - - _createTabs: function() { - // this could be done using z-index. just imagine few cards stacked up. - // Check if options has tab data. - // Originally we will be pulling tab data from developer. - // Now we are building upon dummy data. - this.tabHead = this._createElement("<div></div>").addClass("plate-setup-tab-head"); - $(this.tabContainer).append(this.tabHead); - - var tabData = this.options.attributes.tabs; - var that = this; - - tabData.forEach(function (tab, tabIndex) { - that.allTabs[tabIndex] = that._createElement("<div></div>").addClass("plate-setup-tab"); - $(that.allTabs[tabIndex]).data("index", tabIndex) - .text(tab.name); - - $(that.allTabs[tabIndex]).click(function() { - that._tabClickHandler(this); - }); - - $(that.tabHead).append(that.allTabs[tabIndex]); - }); - - this.tabDataContainer = this._createElement("<div></div>").addClass("plate-setup-tab-data-container"); - $(this.tabContainer).append(this.tabDataContainer); - - this._addDataTabs(tabData); - - $(this.allTabs[0]).click(); - - this._addTabData(); - }, - - _tabClickHandler: function(clickedTab) { - - if (this.selectedTab) { - $(this.selectedTab).removeClass("plate-setup-tab-selected") - .addClass("plate-setup-tab"); - - var previouslyClickedTabIndex = $(this.selectedTab).data("index"); - $(this.allDataTabs[previouslyClickedTabIndex]).css("z-index", 0); - this.readOnlyHandler(); - } - - $(clickedTab).addClass("plate-setup-tab-selected"); - - this.selectedTab = clickedTab; - - var clickedTabIndex = $(clickedTab).data("index"); - $(this.allDataTabs[clickedTabIndex]).css("z-index", 1000); - }, - - _addDataTabs: function(tabs) { - - var tabIndex = 0; - - for (var tabData in tabs) { - this.allDataTabs[tabIndex++] = this._createElement("<div></div>").addClass("plate-setup-data-div") - .css("z-index", 0); - $(this.tabDataContainer).append(this.allDataTabs[tabIndex - 1]); - } - } - }; - } -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.undoRedoManager = function(THIS) { - - return { - - undoRedoArray: [], - - actionPointer: null, - - addToUndoRedo: function(data) { - - if (this.actionPointer != null) { - var i = this.actionPointer + 1; - if (i < this.undoRedoArray.length) { - this.undoRedoArray.splice(i, this.undoRedoArray.length - i); - } - } - this.actionPointer = null; - this.undoRedoArray.push($.extend(true, {}, data)); - }, - - _configureUndoRedoArray: function() { - - var data = { - checkboxes: [], - derivative: {}, - selectedAreas: [{ - minRow: 0, - minCol: 0, - maxRow: 0, - maxCol: 0 - }], - focalWell: { - row: 0, - col: 0 - } - }; - - this.undoRedoArray = []; - this.actionPointer = null; - this.undoRedoArray.push($.extend({}, data)); - }, - - undo: function() { - console.log("undo"); - return this.shiftUndoRedo(-1); - }, - - redo: function() { - console.log("redo"); - return this.shiftUndoRedo(1); - }, - - shiftUndoRedo: function (pointerDiff) { - var pointer = this.actionPointer; - if (pointer == null) { - pointer = this.undoRedoArray.length - 1; - } - pointer += pointerDiff; - return this.setUndoRedo(pointer); - }, - - setUndoRedo: function (pointer) { - if (pointer < 0) { - return false; - } - if (pointer >= this.undoRedoArray.length) { - return false; - } - this.undoRedoActive = true; - this.setData(this.undoRedoArray[pointer]); - this.actionPointer = pointer; - this.undoRedoActive = false; - this.derivativeChange(); - return true; - } - } - }; - -})(jQuery, fabric); -var plateLayOutWidget = plateLayOutWidget || {}; - -(function($, fabric) { - - plateLayOutWidget.wellArea = function(fabric) { - - return { - - _areasToTiles: function(areas) { - //Convert areas to tiles - var cols = this.dimensions.cols; - var that = this; - return areas.reduce(function(tiles, area) { - if (area) { - for (var r = area.minRow; r <= area.maxRow; r++) { - for (var c = area.minCol; c <= area.maxCol; c++) { - var tile = that.allTiles[c + cols * r]; - if (tiles.indexOf(tile) < 0) { - if (that.disableAddDeleteWell){ - if(that.addressAllowToEdit.indexOf(tile.address) >= 0){ - tiles.push(tile); - } - } else { - tiles.push(tile); - } - } - } - } - } - return tiles; - }, []); - }, - - _encodeArea: function(area) { - //Encode area as string - if ((area.minRow == area.maxRow) && (area.minCol == area.maxCol)) { - return this.rowIndex[area.minRow] + area.minCol.toString(10); - } else { - return this.rowIndex[area.minRow] + area.minCol.toString(10) + ":" + this.rowIndex[area.maxRow] + area.maxCol.toString(10); - } - }, - - _encodeAreas: function(areas) { - //Encode an array of areas as a string - var that = this; - return areas.map(function(area) { - return that._encodeArea(area); - }).join(","); - }, - - _decodeWell: function(wellAddress) { - var that = this; - var adRx = new RegExp("^\\s*(" + that.rowIndex.join("|") + ")(\\d+)\\s*$") - var rcRx = /^\s*R(\d+)C(\d+)\s*$/i; - - var match; - match = wellAddress.match(adRx); - if (match) { - var row = that.rowIndex.indexOf(match[1]); - if (row >= 0) { - return { - row: row, - col: parseInt(match[2]) - 1 - }; - } - } - match = wellAddress.match(rcRx); - if (match) { - return { - row: parseInt(match[1]) - 1, - col: parseInt(match[2]) - 1 - }; - } - - throw "Invalid well address: " + wellAddress; - }, - - _decodeArea: function(areaAddress) { - //Decode single area as string - var that = this; - var wells = areaAddress.split(":").map(function(wellAddress) { - return that._decodeWell(wellAddress); - }) - if (wells.length == 1) { - return { - minRow: wells[0].row, - minCol: wells[0].col, - maxRow: wells[0].row, - maxCol: wells[0].col - } - } else if (wells.length == 2) { - var minRow = Math.min(wells[0].row, wells[1].row) - return { - minRow: Math.min(wells[0].row, wells[1].row), - minCol: Math.min(wells[0].col, wells[1].col), - maxRow: Math.max(wells[0].row, wells[1].row), - maxCol: Math.max(wells[0].col, wells[1].col) - } - } else { - throw "Invalid address: " + areaAddress; - } - }, - - _decodeAreas: function(areasAddress) { - //Decode single area as string - var that = this; - return areasAddress.split(",").map(function(areaAddress) { - return that._decodeArea(areaAddress); - }); - }, - - _wellToArea: function(well) { - //Convert a well to an area - return { - minCol: well.col, - minRow: well.row, - maxCol: well.col, - maxRow: well.row - } - }, - - _wellInArea: function(well, area) { - //Determine if a well lies within an area - return well.row >= area.minRow && well.row <= area.maxRow && well.col >= area.minCol && well.col <= area.maxCol; - }, - - _coordsToRect: function(startCoords, endCoords) { - //Convert two XY coords to a bounding box - var left = Math.min(startCoords.x, endCoords.x); - var top = Math.min(startCoords.y, endCoords.y); - var height = Math.abs(endCoords.y - startCoords.y); - var width = Math.abs(endCoords.x - startCoords.x); - return { - top: top, - left: left, - height: height, - width: width - }; - }, - - _coordIndex: function(v, count) { - var i; - if (v < 0) { - i = 0; - } else if (v >= count) { - i = count - 1; - } else { - i = Math.floor(v); - } - return i; - }, - - _coordsToWell: function(coord) { - //Convert a coordinate to a well - var cols = this.dimensions.cols; - var rows = this.dimensions.rows; - - var w = this.sizes.spacing; - var m = this.sizes.label_spacing; - - var x = (coord.x - m) / w; - var y = (coord.y - m) / w; - - var row = this._coordIndex(y, rows); - var col = this._coordIndex(x, cols); - - return { - row: row, - col: col, - }; - }, - - _wellToCoords: function(well, center) { - //Convert a well to a coordinate - var w = this.sizes.spacing; - var m = this.sizes.label_spacing; - var x = well.col * w + m; - var y = well.row * w + m; - if (center) { - var hw = w/2; - x = x + hw; - y = y + hw; - } - - return { - x: x, - y: y - }; - }, - - _areaToRect: function(area) { - //Convert area to rectangle - var rows = area.maxRow - area.minRow + 1; - var cols = area.maxCol - area.minCol + 1; - - var w = this.sizes.spacing; - var m = this.sizes.label_spacing; - - return { - top: area.minRow * w + m, - left: area.minCol * w + m, - height: rows * w, - width: cols * w - } - }, - - _rectToArea: function(rect) { - //Convert a rectangular region to an area - var rows = this.dimensions.rows; - var cols = this.dimensions.cols; - - var w = this.sizes.spacing; - var m = this.sizes.label_spacing; - - var left = (rect.left - m) / w; - var top = (rect.top - m) / w; - var height = rect.height / w; - var width = rect.width / w; - var right = left + width; - var bottom = top + height; - - //select whole row - if (right < 0) { - right = cols; - } - if (left >= cols) { - left = 0; - } - //select whole col - if (bottom < 0) { - bottom = rows; - } - if (top <= 0) { - top = 0; - } - - return { - minCol: this._coordIndex(left, cols), - minRow: this._coordIndex(top, rows), - maxCol: this._coordIndex(right, cols), - maxRow: this._coordIndex(bottom, rows) - }; - } - - } - } -})(jQuery, fabric); \ No newline at end of file diff --git a/dist/js/plate-map.min.js b/dist/js/plate-map.min.js deleted file mode 100755 index e20d70f..0000000 --- a/dist/js/plate-map.min.js +++ /dev/null @@ -1,2 +0,0 @@ -var plateLayOutWidget=plateLayOutWidget||{};!function(u,e){plateLayOutWidget.addDataOnChange=function(){return{_addAllData:function(e){if(this.allSelectedObjects)for(var t=this.allSelectedObjects.length,i=[],a=0;a<t;a++){var n,l=this.allSelectedObjects[a];l.index in this.engine.derivative?n=this.engine.derivative[l.index]:(n=u.extend(!0,{},this.defaultWell),this.engine.derivative[l.index]=n);var s=this.processWellData(e,n,t,i);if(i=s.wells,n=s.well,this.engine.wellEmpty(n))if(this.emptyWellWithDefaultVal&&this.disableAddDeleteWell){var r=JSON.parse(JSON.stringify(n)),o=this.emptyWellWithDefaultVal;for(var d in o)d in r&&(r[d]=o[d],this._applyFieldData(d,o[d]));this.engine.derivative[l.index]=r}else delete this.engine.derivative[l.index]}this._getAllMultipleVal(i),this.applyFieldWarning(i),this._colorMixer(),this.derivativeChange()},processWellData:function(e,t,i,a){for(var n in a||(a=[]),e){var l;if(void 0!==e[n]&&null!==e[n])if(e[n].multi){var s=e[n],r=t[n],o=this._getMultiData(r,s,n,i);l=JSON.parse(JSON.stringify(o))}else l=JSON.parse(JSON.stringify(e[n]));else l=JSON.parse(JSON.stringify(e[n]));t[n]=l,a.push(t)}return{well:t,wells:a}},_getMultiData:function(e,t,i,a){var n=t.added,l=t.removed;if(n)if(e)if(n.value){var s=!0;for(var r in e){e[r][i].toString()===n.id.toString()&&(s=!1,e=e.map(function(e){if(e[i].toString()===n.id.toString())for(var t in e)t in n.value&&t!==i&&(1===a?e[t]=n.value[t]:n.value[t]&&(e[t]=n.value[t]));return e}))}s&&e.push(n.value)}else e.indexOf(n)<0&&e.push(n);else e=[],n.value?e.push(n.value):n&&e.push(n);var o,d=function(e,t){var i=[];for(var a in e)parseInt(a)!==parseInt(t)&&i.push(e[a]);return i};if(l)if(l.value){for(var r in e){e[r][i].toString()===l.id.toString()&&(o=r)}e=d(e,o)}else e&&0<=(o=e.indexOf(l))&&(e=d(e,o));return e&&0==e.length&&(e=null),e},_colorMixer:function(){if(!this.undoRedoActive){var e=this.createObject();this.addToUndoRedo(e)}this.engine.searchAndStack(),this.engine.applyColors(),this.mainFabricCanvas.renderAll()},derivativeChange:function(){this._trigger("updateWells",null,this.createObject())},createObject:function(){return{derivative:u.extend(!0,{},this.engine.derivative),checkboxes:this.globalSelectedAttributes.slice(),selectedAreas:this.selectedAreas.slice(),focalWell:this.focalWell,requiredField:this.requiredField}}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};jQuery,fabric,plateLayOutWidget.addDataToFields=function(){return{_addDataToTabFields:function(e){for(var t in e)this._applyFieldData(t,e[t])},_applyFieldData:function(e,t){this.fieldMap[e].setValue(t)}}};plateLayOutWidget=plateLayOutWidget||{};!function(u,e){plateLayOutWidget.addTabData=function(){return{fieldList:[],fieldMap:{},autoId:1,_addTabData:function(){var e=this.options.attributes.tabs,r=this;this.requiredField=[];var o=[];e.forEach(function(e,t){if(e.fields){var i=e.fields,a=[];for(var n in i){var l,s=i[n];s.id||(s.id="Auto"+r.autoId++,console.log("Field autoassigned id "+s.id)),s.type||(s.type="text",console.log("Field "+s.id+" autoassigned type "+s.type)),"multiplex"===s.type?(l=r._makeMultiplexField(s,t,a),o.push(l)):(l=r._makeRegularField(s,t,a,!0),"multiselect"===s.type&&o.push(l))}r.allDataTabs[t].fields=a}else console.log("unknown format in field initialization")}),r.multipleFieldList=o},_makeSubField:function(e,t,i){var a=this;e.id||(e.id="Auto"+a.autoId++,console.log("Field autoassigned id "+e.id)),e.type||(e.type="text",console.log("Field "+e.id+" autoassigned type "+e.type));var n=a._createElement("<div></div>").addClass("plate-setup-tab-default-field"),l=a._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"),s=a._createElement("<div></div>").addClass("plate-setup-tab-field-right-side"),r=a._createElement("<div></div>").addClass("plate-setup-tab-name").text(e.name),o=a._createElement("<div></div>").addClass("plate-setup-tab-field-container");u(s).append(r),u(s).append(o),u(n).append(l),u(n).append(s),u(a.allDataTabs[t]).append(n);var d={id:e.id,name:e.name,root:n,data:e,required:e.required||!1};return i.push(d),a.fieldMap[e.id]=d},_makeRegularField:function(e,t,i,a){var n=this,l=n._createElement("<div></div>").addClass("plate-setup-tab-default-field"),s=n._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"),r=n._createElement("<div></div>").addClass("plate-setup-tab-field-right-side "),o=n._createElement("<div></div>").addClass("plate-setup-tab-name").text(e.name),d=n._createElement("<div></div>").addClass("plate-setup-tab-field-container");r.append(o),r.append(d),l.append(s),l.append(r),n.allDataTabs[t].append(l);var u={id:e.id,name:e.name,root:l,data:e,required:e.required};return u.required&&n.requiredField.push(u.id),i.push(u),n.fieldList.push(u),n.fieldMap[u.id]=u,a&&n._addCheckBox(u),n._createField(u),u.onChange=function(){var e=u.getValue(),t={};t[u.id]=e,n._addAllData(t)},u},_makeMultiplexField:function(e,t,i){var a=this,n=a._createElement("<div></div>").addClass("plate-setup-tab-default-field"),l=a._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"),s=a._createElement("<div></div>").addClass("plate-setup-tab-field-right-side "),r=a._createElement("<div></div>").addClass("plate-setup-tab-name").text(e.name),o=a._createElement("<div></div>").addClass("plate-setup-tab-field-container");s.append(r),s.append(o),n.append(l),n.append(s),a.allDataTabs[t].append(n);var d={id:e.id,name:e.name,root:n,data:e,required:e.required};i.push(d),a.fieldList.push(d),a.fieldMap[e.id]=d;var u=[],c=[];for(var f in e.multiplexFields){var h=e.multiplexFields[f],p=a._makeSubField(h,t,i);u.push(p),h.required&&c.push(p.id)}return(d.required||c.length)&&this.requiredField.push({multiplexId:d.id,subFields:c}),d.subFieldList=u,a._createField(d),a._addCheckBox(d),u.forEach(function(s){s.mainMultiplexField=d,i.push(s),a._createField(s),a._addCheckBox(s),delete a.defaultWell[s.id],s.onChange=function(){var t=s.getValue(),i=s.mainMultiplexField,a=i.singleSelectValue(),e={};e[i.id]=a,e[s.id]=t;var n={id:a,value:e};d._changeMultiFieldValue(n,null);var l=i.detailData;null!==l&&(a=i.singleSelectValue(),l=l.map(function(e){return e[i.id]===a&&(e[s.id]=t),e})),i.detailData=l}}),d.getValue=function(){var e=d.input.select2("data");return e.length?e.map(function(e){return e.id}):null},d}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(s,e){plateLayOutWidget.addWarningMsg=function(){return{fieldWarningMsg:function(e,t,i){var a="fieldWarning"+e.id,n=s("<span>").html(this._assets.warningImg).attr("id",a).addClass("plate-field-warning-image");if(i){if(e.root.find("#"+a).length<=0){e.root.find(".plate-setup-tab-name").text(" "+e.name),e.root.find(".plate-setup-tab-name").prepend(n);var l=s("<div/>").addClass("pop-out-text");l.text(t),e.root.find(".plate-setup-tab-name").append(l),s("#"+a).hover(function(e){l[0].style.display="flex"},function(){l.hide()})}}else 0<e.root.find("#"+a).length&&(e.root.find(".plate-setup-tab-name").text(e.name),s("#"+a).remove())},removeWarningMsg:function(e,t,i){var a="fieldWarning"+e.id,n=s("<span>").html(this._assets.warningImg).attr("id",a).addClass("plate-field-warning-image");if(i){e.root.find(".plate-setup-tab-name").append(n);var l=s("<div/>").addClass("pop-out-text");l.text(t),e.root.find(".plate-setup-tab-name").append(l),s("#"+a).hover(function(e){l[0].style.display="inline-block"},function(){l.hide()})}else s("#"+a).remove(),0<e.root.find("#"+a).length&&s("#"+a).remove()},applyFieldWarning:function(e){var i=this,a={};i.fieldList.forEach(function(e){a[e.id]=[]}),e.forEach(function(e){if(!i.engine.wellEmpty(e))for(var t in a)t in e?a[t].push(e[t]):a[t].push(null)});for(var t=0;t<i.fieldList.length;t++){var n=i.fieldList[t];if(n.applyMultiplexSubFieldColor)n.applyMultiplexSubFieldColor(a[n.id]);else if(n.required){var l=!1;a[n.id].forEach(function(e){e instanceof Array?0===e.length&&(l=!0):null===e&&(l=!0)}),i.fieldWarningMsg(n,"required field",l)}}}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(d,e){plateLayOutWidget.bottomTable=function(){return{_bottomScreen:function(){this.bottomContainer=this._createElement("<div></div>").addClass("plate-setup-bottom-container"),this.bottomTableContainer=this._createElement("<div></div>").addClass("plate-setup-bottom-table-container"),this.bottomTable=this._createElement("<table></table>").addClass("plate-setup-bottom-table"),this.bottomTableContainer.append(this.bottomTable),this.bottomContainer.append(this.bottomTableContainer),this.container.append(this.bottomContainer)},addBottomTableHeadings:function(){this.bottomRow=this._createElement("<tr></tr>");var e=this._createElement("<th></th>").text("Group");this.bottomRow.prepend(e),this.bottomTable.empty(),this.bottomTable.append(this.bottomRow),this.rowCounter=1;for(var t=0;t<this.globalSelectedAttributes.length;t++){var i=this.globalSelectedAttributes[t],a=this.fieldMap[i];e=this._createElement("<th></th>").text(a.name);this.bottomRow.append(e),this.rowCounter=this.rowCounter+1}this.adjustFieldWidth(this.bottomRow)},tileAttrText:function(e,t){var i=this.engine.derivative[e.index];return this.fieldMap[t].getText(i[t])},addBottomTableRow:function(e,i){var a=this,t=this.allTiles[i[0]],n=this._createElement("<tr></tr>"),l=this._createElement("<td></td>").addClass("plate-setup-bottom-id"),s=this._createElement("<button/>");s.addClass("plate-setup-color-text"),s.text(e),l.append(s),s.click(function(e){var t=i.map(function(e){return a.indexToAddress(e)});e.ctrlKey&&a.getSelectedAddress().forEach(function(e){t.indexOf(e)<0&&t.push(e)}),a.setSelectedWell(t),a._trigger("selectedWells",null,{selectedAddress:a.getSelectedAddress()})}),0<e&&(e=(e-1)%(this.colorPairs.length-1)+1);var r=this.colorPairs[e];l.css("background","linear-gradient(to right, "+r[0]+" , "+r[1]+")"),n.append(l);for(var o=0;o<this.globalSelectedAttributes.length;o++){var d=this.globalSelectedAttributes[o],u=this.tileAttrText(t,d),c=this._createElement("<td></td>").text(u);n.append(c)}this.bottomTable.append(n),this.adjustFieldWidth(n)},bottomForFirstTime:function(){this.addBottomTableHeadings();var e=this._createElement("<tr></tr>"),t=this.colorPairs[0],i=this._createElement("<td></td>");i.css("background","-webkit-linear-gradient(left, "+t[0]+" , "+t[1]+")"),e.append(i),this.bottomTable.append(e),this.createExportButton()},adjustFieldWidth:function(e){var t=this.rowCounter;1024<150*t&&e.css("width",152*t+"px")},downloadCSV:function(e,t){var i,a;i=new Blob([e],{type:"text/csv"}),(a=document.createElement("a")).download=t,a.href=window.URL.createObjectURL(i),a.style.display="none",document.body.appendChild(a),a.click()},exportData:function(e){var t=[],i=document.querySelectorAll("table tr"),a={},n=this.engine.stackUpWithColor,l=this.getDimensions(),s=this;for(var r in n)a[r]=n[r].map(function(e){return s.indexToAddress(e,l)});for(var o=0;o<i.length;o++){for(var d=[],u=i[o].querySelectorAll("td, th"),c=0;c<u.length;c++){var f="";if(u[c].innerText&&(f="csv"===e?'"'+u[c].innerText.replace(/"/g,'""')+'"':u[c].innerText),d.push(f),0===o&&0===c&&("csv"===e?d.push('"Location"'):"clipboard"===e&&d.push("Location")),0!==o&&0===c){var h="";a[parseInt(u[c].innerText)]&&("csv"===e?h='"'+a[parseInt(u[c].innerText)].join(",")+'"':"clipboard"===e&&(h=a[parseInt(u[c].innerText)].join(","))),d.push(h)}}"csv"===e?t.push(d.join(",")):"clipboard"===e&&t.push(d.join("\t"))}if("csv"===e)this.downloadCSV(t.join("\n"),"table.csv");else if("clipboard"===e)return t.join("\n")},createExportButton:function(){var e=this,t=d("<div>").addClass("plate-setup-bottom-control-container"),i=d("<div>").addClass("plate-setup-overlay-text-container");i.text("Color groups"),t.append(i);var a=d("<div>").addClass("plate-setup-overlay-bottom-button-container"),n=d("<button/>").addClass("plate-setup-button");function l(){n.text("Export CSV"),n[0].classList.remove("plate-setup-clicked-button"),n.addClass("plate-setup-button")}n.text("Export CSV"),a.append(n),n.click(function(){e.exportData("csv"),n.text("Exported"),n[0].classList.remove("plate-setup-button"),n.addClass("plate-setup-clicked-button"),setTimeout(l,3e3)});var s=d("<button/>").addClass("plate-setup-button");s.text("Copy To Clipboard"),a.append(s);var r=new ClipboardJS(s.get(0),{text:function(){return e.exportData("clipboard")}});function o(){s.text("Copy To Clipboard"),s[0].classList.remove("plate-setup-clicked-button"),s.addClass("plate-setup-button")}r.on("success",function(e){s.text("Copied as tab-delimited format"),s[0].classList.remove("plate-setup-button"),s.addClass("plate-setup-clicked-button"),setTimeout(o,3e3)}),r.on("error",function(e){s.text("Failed to copy table to clipboard: browser may be incompatible"),setTimeout(o,3e3)}),t.append(a),d(".plate-setup-bottom-container").prepend(t)}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(e,i){plateLayOutWidget.canvas=function(){return{allSelectedObjects:null,allPreviouslySelectedObjects:null,colorPointer:0,goldenRatio:.618033988749895,_createCanvas:function(){this.normalCanvas=this._createElement("<canvas>").attr("id","DNAcanvas"),e(this.canvasContainer).append(this.normalCanvas)},_initiateFabricCanvas:function(){var e=this.canvasContainer.width(),t=this.canvasContainer.height();this._setCanvasArea(e,t),this.mainFabricCanvas=new i.Canvas("DNAcanvas",{backgroundColor:"#f5f5f5",selection:!1,stateful:!1,hoverCursor:"pointer",renderOnAddRemove:!1}).setWidth(e).setHeight(t)}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(l,e){plateLayOutWidget.checkBox=function(){return{globalSelectedAttributes:[],_addCheckBox:function(e){var t=l("<span>").html(this._assets.dontImg).addClass("plate-setup-tab-check-box bg-light").data("clicked",!1);t.data("linkedFieldId",e.id),e.root.find(".plate-setup-tab-field-left-side").empty().append(t),this._applyCheckboxHandler(t),e.checkbox=t},_applyCheckboxHandler:function(e){var n=this;e.click(function(e,t){var i=l(this),a={};a[i.data("linkedFieldId")]=!i.data("clicked"),n.changeCheckboxes(a)})},changeSubFieldsCheckboxes:function(e,n){var l=this,s=[];return e.subFieldList.forEach(function(e){var t=e.checkbox,i=t.data("linkedFieldId"),a=t.data("clicked");i in n&&(a=Boolean(n[i])),t.data("clicked",a),a?(t.html(l._assets.doImg),s.push(e.id)):t.html(l._assets.dontImg)}),s},changeCheckboxes:function(e){for(var t=[],i={},a=0;a<this.fieldList.length;a++){var n=this.fieldList[a];if(n.checkbox){n.subFieldList&&(i[n.id]=this.changeSubFieldsCheckboxes(n,e));var l=n.checkbox,s=l.data("linkedFieldId"),r=l.data("clicked");s in e&&(r=Boolean(e[s])),l.data("clicked",r),r?(t.push(s),l.html(this._assets.doImg)):l.html(this._assets.dontImg)}}this.globalSelectedMultiplexSubfield=i,this.globalSelectedAttributes=t,this._clearPresetSelection(),this._colorMixer()},setSubFieldCheckboxes:function(e,n){var l=this,s=[];return e.subFieldList.forEach(function(e){var t=e.checkbox,i=t.data("linkedFieldId"),a=0<=n.indexOf(i);t.data("clicked",a),a?(t.html(l._assets.doImg),s.push(e.id)):t.html(l._assets.dontImg)}),s},setCheckboxes:function(e){e=e||[];for(var t=[],i={},a=0;a<this.fieldList.length;a++){var n=this.fieldList[a];if(n.checkbox){n.subFieldList&&(i[n.id]=this.setSubFieldCheckboxes(n,e));var l=n.checkbox,s=l.data("linkedFieldId"),r=0<=e.indexOf(s);l.data("clicked",r),r?(t.push(s),l.html(this._assets.doImg)):l.html(this._assets.dontImg)}}this.globalSelectedMultiplexSubfield=i,this.globalSelectedAttributes=t,this._clearPresetSelection(),this._colorMixer()}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};jQuery,fabric,plateLayOutWidget.colorManager=function(){return{colorPairs:[["#e6e6e6","#808080"],["#66e8ff","#0082c8"],["#ff7fb1","#e6194b"],["#a2ffb1","#3cb44b"],["#f784ff","#911eb4"],["#ffe897","#f58231"],["#6666ff","#0000FF"],["#ffff7f","#ffe119"],["#acffff","#46f0f0"],["#ff98ff","#f032e6"],["#ffffa2","#d2f53c"],["#ffffff","#fabebe"],["#66e6e6","#008080"],["#ffffff","#e6beff"],["#ffd48e","#aa6e28"],["#e66666","#800000"],["#ffffff","#aaffc3"],["#e6e666","#808000"],["#ffffff","#ffd8b1"],["#66a9ef","#004389"],["#ff6672","#a7000c"],["#66db72","#00750c"],["#b866db","#520075"],["#ffa966","#b64300"],["#ffff66","#c0a200"],["#6dffff","#07b1b1"],["#ff66ff","#b100a7"],["#f9ff66","#93b600"],["#ffe5e5","#bb7f7f"],["#66a7a7","#004141"],["#ffe5ff","#a77fc0"],["#d19566","#6b2f00"],["#ffffef","#c0bb89"],["#d1ffea","#6bc084"],["#a7a766","#414100"],["#ffffd8","#c09972"],["#a5ffff","#3fc1ff"],["#ffbef0","#ff588a"],["#e1fff0","#7bf38a"],["#ffc3ff","#d05df3"],["#ffffd6","#ffc170"],["#a5a5ff","#3f3fff"],["#ffffbe","#ffff58"],["#ebffff","#85ffff"],["#ffd7ff","#ff71ff"],["#a5ffff","#3fbfbf"],["#ffffcd","#e9ad67"],["#ffa5a5","#bf3f3f"],["#ffffa5","#bfbf3f"]]}};plateLayOutWidget=plateLayOutWidget||{};!function(e,u){plateLayOutWidget.createCanvasElements=function(){return{scaleFactor:1,baseSizes:{spacing:48,tile_radius:22,center_radius_complete:10,center_radius_incomplete:14,label_size:14,label_spacing:24,text_size:13,stroke:.5,gap:2},_setCanvasArea:function(e,t){this.scaleFactor=Math.min(t/(this.dimensions.rows*this.baseSizes.spacing+this.baseSizes.label_spacing),e/(this.dimensions.cols*this.baseSizes.spacing+this.baseSizes.label_spacing));var i={};for(var a in this.baseSizes)i[a]=this.baseSizes[a]*this.scaleFactor;this.sizes=i},_canvas:function(){this._fixRowAndColumn(),this._putCircles()},_fixRowAndColumn:function(){for(var e=this.dimensions.cols,t=this.dimensions.rows,i=this.sizes.spacing,a=this.sizes.label_spacing/2,n=this.sizes.label_spacing+this.sizes.spacing/2,l=this.sizes.label_size,s=a,r=n,o=1;o<=e;o++){var d=new u.IText(o.toString(),{fill:"black",originX:"center",originY:"center",fontSize:l,top:s,left:r,fontFamily:'"Roboto", Arial, sans-serif',selectable:!1,fontWeight:"400"});r+=i,this.mainFabricCanvas.add(d)}s=n,r=a;for(o=1;o<=t;o++){d=new u.IText(this.rowIndex[o-1],{fill:"black",originX:"center",originY:"center",fontSize:l,top:s,left:r,fontFamily:'"Roboto", Arial, sans-serif',selectable:!1,fontWeight:"400"});s+=i,this.mainFabricCanvas.add(d)}},_putCircles:function(){for(var e=this.dimensions.cols,t=this.dimensions.rows,i=0,a=0;a<t;a++)for(var n=0;n<e;n++){this.allTiles.length;var l=this._createTile(a,n);l.index=i++,this.allTiles.push(l),this.mainFabricCanvas.add(l.background),this.mainFabricCanvas.add(l.highlight),this.mainFabricCanvas.add(l.circle),this.mainFabricCanvas.add(l.circleCenter),this.mainFabricCanvas.add(l.circleText)}this._addLargeRectangleOverlay(),this._fabricEvents()},_createTile:function(e,t){var i={visible:!1,colorIndex:null};i.row=e,i.col=t,i.address=this.rowIndex[e]+(t+1);var a=(e+1)*this.sizes.spacing,n=(t+1)*this.sizes.spacing;return i.background=new u.Circle({top:a,left:n,radius:this.sizes.tile_radius,originX:"center",originY:"center",hasControls:!1,hasBorders:!1,lockMovementX:!0,lockMovementY:!0,evented:!1}),i.background.setGradient("fill",{type:"radial",x1:this.sizes.tile_radius,x2:this.sizes.tile_radius,y1:this.sizes.tile_radius+this.sizes.gap,y2:this.sizes.tile_radius+this.sizes.gap,r1:this.sizes.tile_radius-this.sizes.gap,r2:this.sizes.tile_radius,colorStops:{0:"rgba(0,0,0,0.1)",1:"rgba(0,0,0,0.2)"}}),i.highlight=new u.Rect({originX:"center",originY:"center",top:a,left:n,width:this.sizes.spacing,height:this.sizes.spacing,fill:"rgba(0,0,0,0.4)",evented:!1,visible:!1}),i.circle=new u.Circle({originX:"center",originY:"center",top:a,left:n,radius:this.sizes.tile_radius,stroke:"gray",strokeWidth:this.sizes.stroke,evented:!1,visible:!1}),i.circleCenter=new u.Circle({originX:"center",originY:"center",top:a,left:n,radius:this.sizes.center_radius_incomplete,fill:"white",stroke:"gray",strokeWidth:this.sizes.stroke,evented:!1,visible:!1}),i.circleText=new u.IText("",{originX:"center",originY:"center",top:a,left:n,fill:"black",fontFamily:'"Roboto", Arial, sans-serif',fontSize:this.sizes.text_size,lockScalingX:!0,lockScalingY:!0,evented:!1,visible:!1}),i},setTileComplete:function(e,t){e.circleText.fontWeight=t?(e.circleCenter.radius=this.sizes.center_radius_complete,e.circleText.fill="black","normal"):(e.circleCenter.radius=this.sizes.center_radius_incomplete,e.circleText.fill="red","bold")},setTileVisible:function(e,t){e.visible=t,e.circle.visible=e.visible,e.circleCenter.visible=e.visible,e.circleText.visible=e.visible},setTileColor:function(e,t,i){this.setTileVisible(e,!0),e.colorIndex=parseInt(t),e.circleText.text=String(e.colorIndex),0<t&&(t=(t-1)%(this.colorPairs.length-1)+1);var a=this.colorPairs[t];e.circle.setGradient("fill",{y2:2*this.sizes.tile_radius,colorStops:a})},_addLargeRectangleOverlay:function(){this.overLay=new u.Rect({width:632,height:482,left:0,top:0,opacity:0,originX:"left",originY:"top",lockMovementY:!0,lockMovementX:!0,selectable:!1}),this.mainFabricCanvas.add(this.overLay)}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(f,e){plateLayOutWidget.createField=function(){return{_createField:function(e){switch(e.data.type){case"text":this._createTextField(e);break;case"numeric":this._createNumericField(e);break;case"select":this._createSelectField(e);break;case"multiselect":this._createMultiSelectField(e);break;case"boolean":this._createBooleanField(e);break;case"multiplex":this._createMultiplexField(e)}},_createTextField:function(i){var e=i.id,t=this._createElement("<input>").attr("id",e).addClass("plate-setup-tab-input");i.root.find(".plate-setup-tab-field-container").append(t),this.defaultWell[e]=null,i.parseValue=function(e){return e=e?String(e):null},i.getValue=function(){var e=t.val().trim();return""==e&&(e=null),e},i.setValue=function(e){t.val(e)},i.getText=function(e){return null==e?"":e},i.disabled=function(e){i.input.prop("disabled",e)},i.parseText=i.parseValue,t.on("input",function(e,t){i.onChange()}),i.input=t},_createOpts:function(e){var t={allowClear:!0,placeholder:"select",minimumResultsForSearch:10};if(e.options)t.data=e.options;else{if(!e.query)throw"Must specify data or query";var i=e.query;e.delay&&(i=this._debounce(e.delay,i)),t.query=i}return t},_createSelectField:function(i){var a=i.id,t=this._createElement("<input/>").attr("id",a).addClass("plate-setup-tab-select-field");i.root.find(".plate-setup-tab-field-container").append(t),this.defaultWell[a]=null;var n=this._createOpts(i.data),l={};n.data.forEach(function(e){l[e.id]=e}),t.select2(n),i.parseValue=function(e){var t=e;if(""==t&&(t=null),null==t)return null;if(t in l)return l[t].id;throw"Invalid value "+e+" for select field "+a},i.disabled=function(e){i.input.prop("disabled",e)},i.getValue=function(){var e=t.select2("data");return e?e.id:null},i.setValue=function(e){e&&(e=l[e]),t.select2("data",e)},i.setOpts=function(e){t.select2("data",{}),n.data=e||[],t.select2(n)},i.getText=function(e){return null==e?"":l[e].text},i.parseText=function(e){var t=e;if(""==t&&(t=null),null==t)return null;if(t in l)return l[t].text;throw"Invalid text value "+e+" for select field "+a},t.on("change",function(e,t){i.onChange()}),i.input=t},_createMultiSelectField:function(l){var i=l.id,a=this,s=this._createElement("<input/>").attr("id",i).addClass("plate-setup-tab-multiselect-field");s.attr("multiple","multiple"),l.root.find(".plate-setup-tab-field-container").append(s),a.defaultWell[i]=null;var r=a._createOpts(l.data);r.multiple=!0;var n={};r.data.forEach(function(e){n[e.id]=e}),s.select2(r),l.disabled=function(e){l.input.prop("disabled",e)},l.parseValue=function(e){var t=e;return t=t&&t.length?t.map(function(e){if(e in n)return n[e].id;throw"Invalid value "+e+" for multiselect field "+i}):null},l.setOpts=function(e){var t=l.data.options,i=[];for(var a in t){var n=t[a];0<=e.indexOf(n.id)&&i.push(n)}r.data=i,s.select2(r)},l.getValue=function(){var e=s.select2("data");return e.length?e.map(function(e){return e.id}):null},l.setValue=function(e){e=(e=e||[]).map(function(e){return n[e]}),s.select2("data",e)},l.getText=function(e){return null==e?"":0<e.length?e.map(function(e){return n[e].text}).join("; "):""},l.multiOnChange=function(e,t){e&&(e=e.id.toString()),t&&(t=t.id.toString());var i={};i[l.id]={multi:!0,added:e,removed:t},a._addAllData(i)},l.parseText=function(e){var t=e;return t=t&&t.length?t.map(function(e){if(e in n)return n[e].text;throw"Invalid text value "+e+" for multiselect field "+i}):null},s.on("change",function(e,t){var i=e.added,a=e.removed;l.multiOnChange(i,a)}),l.input=s,a._createDeleteButton(l)},_createNumericField:function(n){var i=n.id,e=n.data,t=this._createElement("<input>").addClass("plate-setup-tab-input").attr("placeholder",e.placeholder||"").attr("id",i);n.root.find(".plate-setup-tab-field-container").append(t),this.defaultWell[i]=null;var a=e.units||[],l=e.defaultUnit||null,s=null;if(l?a.length?a.indexOf(l)<0&&(l=a[0]):a=[l]:a.length&&(l=a[0]),a.length)if(n.units=a,n.hasUnits=!0,n.defaultUnit=l,1==a.length){var r=f("<div></div>").addClass("plate-setup-tab-unit");r.text(l),n.root.find(".plate-setup-tab-field-container").append(r)}else{s=this._createElement("<input/>").attr("id",i).addClass("plate-setup-tab-label-select-field"),n.root.find(".plate-setup-tab-field-container").append(s);var o=null,d={data:a.map(function(e){var t={id:e,text:e};return e==l&&(o=t),t}),allowClear:!1,minimumResultsForSearch:10};s.select2(d),s.select2("data",o)}n.disabled=function(e){n.input.prop("disabled",e),s&&s.prop("disabled",e)},n.setUnitOpts=function(e){n.units=e||null;var t=[],i=n.defaultUnit=null;n.units&&n.units.length&&(n.defaultUnit=n.units[0],t=n.units.map(function(e){var t={id:e,text:e};return e==n.defaultUnit&&(i=t),t}));var a={data:t,allowClear:!1,minimumResultsForSearch:10};s.select2(a),s.select2("data",i)},n.parseValue=function(e){var t;if(f.isPlainObject(e)){if(n.hasUnits)return null===(t=n.parseRegularValue(e.value))?null:{value:t,unit:n.parseUnit(e.unit)};throw"Value must be plain numeric for numeric field "+i}return n.hasUnits?null===(t=n.parseRegularValue(e))?null:{value:t,unit:n.defaultUnit}:n.parseRegularValue(e)},n.getValue=function(){var e=n.getRegularValue();if(null===e||isNaN(e))return null;if(n.hasUnits){var t={value:e,unit:n.getUnit()};if(n.data.hasMultiplexUnit)for(var i in n.data.unitMap){n.data.unitMap[i].forEach(function(e){e.text===t.unit&&(t.unitTypeId=i,t.unitId=e.id)})}return t}return e},n.setValue=function(e){n.hasUnits?f.isPlainObject(e)?(n.setUnit(e.unit||n.defaultUnit),n.setRegularValue(e.value)):(n.setRegularValue(e),n.setUnit(n.defaultUnit)):n.setRegularValue(e)},n.parseRegularValue=function(e){if(null==e)return null;var t=String(e).trim();if(""===t)return null;if(t=Number(e),isNaN(t))throw"Invalid value "+e+" for numeric field "+i;return t},n.getRegularValue=function(){var e=t.val().trim();return e=""==e?null:Number(e)},n.setRegularValue=function(e){t.val(e)},n.parseUnit=function(e){if(null==e||""===e)return n.defaultUnit;for(var t=0;t<a.length;t++)if(e.toLowerCase()==a[t].toLowerCase())return a[t];throw"Invalid unit "+e+" for field "+i},n.getUnit=function(){return s?s.val():n.defaultUnit},n.setUnit=function(e){s&&(null!=(e=e||n.defaultUnit)&&(e={id:e,text:e}),s.select2("data",e))},n.getText=function(e){if("object"==typeof e&&e){var t=e.value,i=e.unit;return null==t?"":(t=t.toString(),i||(i=l),i&&(t=t+" "+i),t)}return n.getRegularText(e)},n.getRegularText=function(e){return null==e?"":e=e.toString()},n.parseText=function(e){var t=n.parseValue(e);return t&&"object"==typeof t?t.value+t.unit:t||null},t.on("input",function(){var e=n.getRegularValue();isNaN(e)?t.addClass("invalid"):t.removeClass("invalid"),n.onChange()}),s&&s.on("change",function(){n.onChange()}),n.input=t,n.unitInput=s},_createBooleanField:function(t){var i=t.id,a=this._createElement("<input/>").attr("id",i).addClass("plate-setup-tab-select-field");this.defaultWell[i]=null,t.root.find(".plate-setup-tab-field-container").append(a);var n={id:"true",text:"true"},l={id:"false",text:"false"},e={data:[n,l],placeholder:"select",allowClear:!0,minimumResultsForSearch:-1,initSelection:function(e,t){var i=e.val();t({id:i,text:i})}};a.select2(e),t.disabled=function(e){t.input.prop("disabled",e)},t.parseValue=function(e){if(null==e)return null;var t=String(e).trim().toLowerCase();if("true"==t)t=!0;else if("false"==t)t=!1;else{if(""!=t)throw"Invalid value "+e+" for boolean field "+i;t=null}return t},t.getValue=function(){switch(a.val()){case"true":return!0;case"false":return!1;default:return null}},t.setValue=function(e){e=1==e||"true"==e?n:0==e||"false"==e?l:null,a.select2("data",e)},t.getText=function(e){return null==e?"":e.toString()},t.parseText=t.parseValue,a.on("change",function(e){t.onChange()}),t.input=a},_createMultiplexField:function(o){var d=this;this._createMultiSelectField(o),d.defaultWell[o.id]=[];var e=d._createElement("<div></div>").addClass("plate-setup-tab-name-singleSelect").text("Select to edit"),t=d._createElement("<div></div>").addClass("plate-setup-tab-field-container-singleSelect");o.root.find(".plate-setup-tab-field-right-side").append(e,t),o.singleSelect=this._createElement("<input/>").attr("id",o.id+"SingleSelect").addClass("plate-setup-tab-multiplex-single-select-field"),o.singleSelect.appendTo(t),o.singleSelectValue=function(){var e=o.singleSelect.select2("data");return null!=e&&(e=e.id),e};var u=function(e,t){var i={allowClear:!1,placeholder:"select",minimumResultsForSearch:10,data:e||[]};t||(t=i.data.length?i.data[0]:null),o.singleSelect.select2("data",[]),o.singleSelect.select2(i),o.singleSelect.select2("data",t),o.singleSelect.prop("disabled",0==i.data.length)},c=function(){var t=o.singleSelectValue();o.updateSubFieldUnitOpts(t);var e=o.detailData||[],i=null;e.forEach(function(e){e[o.id]===t&&(i=e)}),i?o.subFieldList.forEach(function(e){e.disabled(!1),e.setValue(i[e.id])}):o.subFieldList.forEach(function(e){e.disabled(!0),e.setValue(null)}),d.readOnlyHandler()};u([]),o.singleSelect.on("change",c),o._changeMultiFieldValue=function(e,t){var i,a={};for(var n in o.data.multiplexFields){a[o.data.multiplexFields[n].id]=null}e&&(i=e.value?e.value:(a[o.id]=e.id,a),e={id:e.id,value:i}),t&&(i=t.value?t.value:(a[o.id]=t.id,a),t={id:t.id,value:i});var l={};l[o.id]={multi:!0,added:e,removed:t},d._addAllData(l)};var a=o.setValue;o.setValue=function(e){var t=null;(o.detailData=e)&&e.length&&(t=e.map(function(e){return e[o.id]})),a(t);var i=o.input.select2("data")||[];u(i),c()},o.disabled=function(t){o.input.prop("disabled",t),o.subFieldList.forEach(function(e){e.disabled(t)}),t?e.text("Select to inspect"):e.text("Select to edit")},o.parseValue=function(e){var t=e;return t=t&&t.length?t.map(function(t){var i={};for(var a in i[o.id]=t[o.id],t)o.subFieldList.forEach(function(e){e.id===a&&(i[e.id]=e.parseValue(t[a]))});return i}):null},o.updateSubFieldUnitOpts=function(t){var i;o.data.options.forEach(function(e){e.id===t&&(i=e)}),o.subFieldList.forEach(function(e){e.data.hasMultiplexUnit&&(i&&i.hasOwnProperty("unitOptions")?e.setUnitOpts(i.unitOptions[e.id]):e.setUnitOpts(null))})},o.multiOnChange=function(e,t){o._changeMultiFieldValue(e,t);var i=o.getValue(),l=o.detailData,s=[],a=null;l&&(s=l.map(function(e){return e[o.id]}));var r=[],n=[];i&&(i.forEach(function(a){if(l&&l.forEach(function(e){e[o.id]===a&&r.push(e)}),s.indexOf(a)<0){var n={};n[o.id]=a,o.updateSubFieldUnitOpts(a),o.subFieldList.forEach(function(i){if(i.hasUnits)if(i.data.hasMultiplexUnit)i.disabled(!1),o.data.options.forEach(function(e){if(e.id===a){var t={value:null,unit:i.units[0]};n[i.id]=i.parseValue(t)}});else{i.data.units&&1<i.data.units.length&&i.disabled(!1);var e={value:null,unit:i.defaultUnit};n[i.id]=i.parseValue(e)}else n[i.id]=i.parseValue(null)}),r.push(n)}}),i.forEach(function(t){o.data.options.forEach(function(e){e.id===t&&n.push(e)})}),a=n[i.length-1]),o.detailData=r,u(n,a),c()},o.getText=function(e){if(null===e)return"";if(o.id in d.globalSelectedMultiplexSubfield){var i=d.globalSelectedMultiplexSubfield[o.id],t=[];for(var a in e){var n=e[a],l=[];for(var s in o.data.options){var r=o.data.options[s];r.id===n[o.id]&&l.push(r.text)}o.subFieldList.forEach(function(e){if(0<=i.indexOf(e.id)){var t=e.getText(n[e.id]);l.push(e.name+": "+t)}}),t.push("{"+l.join(", ")+"}")}return t.join(";")}},o.parseText=function(e){if(null===e)return"";var t=[];for(var i in e){var a=e[i],n=[];for(var l in o.data.options){var s=o.data.options[l];s.id===a[o.id]&&n.push(s.text)}o.subFieldList.forEach(function(e){var t=e.getText(a[e.id]);t&&n.push(t)}),t.push(n)}return t},o.checkMultiplexCompletion=function(e){var t=0,i=0,s=!1;function a(e){var t=0,i=0;for(var a in o.subFieldList){var n=o.subFieldList[a],l=e[n.id];n.required&&(s=!0,t++,"object"==typeof l&&l?l.value&&i++:l&&i++)}return i/t}if(e)if(0<e.length)for(var n in e){t++,i+=a(e[n])}else o.required&&(s=!0,t=1);else o.required&&(s=!0,t=1);return{include:s,completionPct:i/t}},o.applyMultiplexSubFieldColor=function(e){var l={};o.subFieldList.forEach(function(e){e.required&&(l[e.id]={field:e,warningStatus:[]})}),e.forEach(function(e){!function(e){for(var t in o.subFieldList){var i=o.subFieldList[t];if(null===e)o.required&&i.required&&l[i.id].warningStatus.push(!0);else if("object"==typeof e)if(0===e.length)o.required&&i.required&&l[i.id].warningStatus.push(!0);else for(var a in e){var n=e[a][i.id];i.required&&("object"==typeof n&&n?n.value?l[i.id].warningStatus.push(!1):l[i.id].warningStatus.push(!0):n?l[i.id].warningStatus.push(!1):l[i.id].warningStatus.push(!0))}}}(e)});var t=[];for(var i in l){var a=l[i].field;if(0<=l[i].warningStatus.indexOf(!0)){var n=a.name+" is a required subfield for "+o.name+", please make sure all "+o.name+" have "+a.name;o.required,d.fieldWarningMsg(a,n,!0),t.push(!0)}else d.fieldWarningMsg(a,"none",!1),t.push(!1)}var s,r=!1;r=!(t.indexOf(!0)<0),s=o.required?o.name+" is a required field, please also fix missing required subfield(s) below":o.name+" is not a required field, please fix missing required subfield(s) below or remove selected "+o.name,d.fieldWarningMsg(o,s,r)},o.parseMainFieldVal=function(e){for(var t=o.data.options,i=0;i<t.length;i++){var a=t[i];if(a.id===e)return a.text}}},_deleteDialog:function(t){var e,i=this,a=t.allSelectedMultipleVal;e=a?Object.keys(a):[];var n=f("<div/>").addClass("delete-dialog modal");function l(){n.hide(),n.remove()}f("body").append(n);var s=f("<div/>").addClass("modal-content").appendTo(n),r=f("<div/>").appendTo(s),o=f("<div/>").addClass("dialog-buttons").css("justify-content","flex-end").appendTo(s);if(0<e.length){f("<p/>").text(t.name+" in selected wells: choose items to delete and click the delete button below").appendTo(r);var d=i._deleteDialogTable(t,a);if(d.appendTo(r),d.addClass("plate-popout-table"),d.find("td").addClass("plate-popout-td"),d.find("th").addClass("plate-popout-th"),d.find("tr").addClass("plate-popout-tr"),!i.readOnly){var u=f("<button class='multiple-field-manage-delete-button'>Delete Checked Items</button>");o.append(u),u.click(function(){d.find("input:checked").each(function(){var e=this.value;t.multiOnChange(null,{id:e})}),i.decideSelectedFields(),l()})}}else f("<p/>").text("No "+t.name+" in the selected wells").appendTo(r);var c=f("<button>Cancel</button>");o.append(c),c.click(l),n.show(),window.onclick=function(e){e.target==n[0]&&l()}},_deleteDialogTable:function(e,a){var n=this,t=[e.name,"Counts"];n.readOnly||t.push("Delete");var i=f("<table/>"),l=f("<thead/>").appendTo(i);f("<tr/>").appendTo(l).append(t.map(function(e){return f("<th/>").text(e)}));var s=f("<tbody/>").appendTo(i);return e.data.options.forEach(function(e){if(e.id in a){var t=f("<tr/>").appendTo(s),i=f("<input type='checkbox'>").prop("value",e.id);f("<td/>").text(e.text).appendTo(t),f("<td/>").text(a[e.id]).appendTo(t),n.readOnly||f("<td/>").append(i).appendTo(t)}}),i},_createDeleteButton:function(e){var t=this,i=f("<button/>").addClass("plate-setup-remove-all-button");i.id=e.id+"Delete",i.text("Manage "+e.name+"...");var a=t._createElement("<div></div>").addClass("plate-setup-remove-all-button-container");a.append(i),e.deleteButton=i,e.root.find(".plate-setup-tab-field-right-side").append(a),i.click(function(){t._deleteDialog(e)})}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(b,e){plateLayOutWidget.engine=function(v){return{engine:{derivative:{},stackUpWithColor:{},stackPointer:2,wellEmpty:function(e){for(var t in e){var i=e[t];if(null!=i){if(!Array.isArray(i))return!1;if(0<i.length)return!1}}return!0},searchAndStack:function(){this.stackUpWithColor={},this.stackPointer=1;var e={};for(var t in this.derivative){for(var i=this.derivative[t],a={},n=0;n<v.globalSelectedAttributes.length;n++){var l=v.globalSelectedAttributes[n];if(l in v.globalSelectedMultiplexSubfield){var s=v.globalSelectedMultiplexSubfield[l],r=[];for(var o in i[l]){var d=i[l][o],u={};u[l]=d[l],s.forEach(function(e){u[e]=d[e]}),r.push(u)}a[l]=r}else null!=i[l]&&(a[l]=i[l])}b.isEmptyObject(a)?e[t]=null:e[t]=JSON.stringify(a)}for(;!b.isEmptyObject(e);){var c=Object.keys(e).map(function(e){return parseFloat(e,10)});c.sort(function(e,t){return e-t});var f=c[0],h=e[f],p=[];if(h){for(n=0;n<c.length;n++){h==e[t=c[n]]&&(p.push(t),this.stackUpWithColor[this.stackPointer]=p,delete e[t])}0<p.length&&this.stackPointer++}else this.stackUpWithColor[0]?this.stackUpWithColor[0].push(f):this.stackUpWithColor[0]=[f],delete e[f]}},applyColors:function(){var e=0,t=0;v.addBottomTableHeadings();for(var i=0;i<v.allTiles.length;i++){var a=v.allTiles[i];v.setTileVisible(a,!1)}for(var n=0;n<this.stackPointer;n++){var l=this.stackUpWithColor[n];if(l)for(var s in v.addBottomTableRow(n,l),l){e++;var r=this.stackUpWithColor[n][s],o=(a=v.allTiles[r],this.derivative[r]);v.setTileColor(a,n,this.stackPointer);var d=this.checkCompletion(o,a);v.setTileComplete(a,1==d),t+=d}}t=Math.floor(100*t/e),isNaN(t)?v.overLayTextContainer.text("Completion Percentage: 0%"):v.overLayTextContainer.text("Completion Percentage: "+t+"%")},checkCompletion:function(e,t){for(var i=0,a=0,n=0;n<v.fieldList.length;n++){var l=v.fieldList[n];if(l.checkMultiplexCompletion){var s=l.checkMultiplexCompletion(e[l.id]);s.include&&(a+=s.completionPct,i++)}else l.required&&(i++,null!==e[l.id]&&a++)}return i===a?1:a/i}}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(u,n){plateLayOutWidget.fabricEvents=function(){return{colorToIndex:{},startCoords:{x:0,y:0},focalWell:{row:0,col:0},selectedAreas:[],_clickCoords:function(e){var t=e.e.target.getBoundingClientRect();return{x:e.e.clientX-t.left,y:e.e.clientY-t.top}},_fabricEvents:function(){var s=this;u(s.target).on("getPlates",function(e,t){s.getPlates(JSON.parse(t))}),s.mainFabricCanvas.on("mouse:down",function(e){s.selecting=!0;var t=s._clickCoords(e),i=s.selectedAreas.slice(),a=s.focalWell,n=s._wellToCoords(a,!0),l=s._coordsToRect(n,t);e.e.ctrlKey?(n=t,l=s._coordsToRect(n,t),a=s._coordsToWell(n),e.e.shiftKey?i=[s._rectToArea(l)]:i.push(s._rectToArea(l))):e.e.shiftKey?i[i.length-1]=s._rectToArea(l):(n=t,l=s._coordsToRect(n,t),a=s._coordsToWell(n),i=[s._rectToArea(l)]),s.startCoords=n,s.setSelection(i,a),s.mainFabricCanvas.renderAll()}),s.mainFabricCanvas.on("mouse:move",function(e){if(s.selecting){var t=s.selectedAreas.slice(),i=s._clickCoords(e),a=s._coordsToRect(s.startCoords,i),n=s._rectToArea(a);n&&(t[t.length-1]=n),s.setSelection(t,s.focalWell),s.mainFabricCanvas.renderAll()}}),s.mainFabricCanvas.on("mouse:up",function(e){s.selecting=!1;var t=s.selectedAreas.slice(),i=s._clickCoords(e),a=s._coordsToRect(s.startCoords,i),n=s._rectToArea(a);n&&(t[t.length-1]=n),s.setSelection(t,s.focalWell),s.decideSelectedFields(),s.mainFabricCanvas.renderAll(),s._trigger("selectedWells",null,{selectedAddress:s.getSelectedAddress()})})},setSelection:function(e,t){this.selectedAreas=e,this.focalWell=t,this.allSelectedObjects=this._areasToTiles(e),this._setSelectedTiles(),this._setFocalWellRect(this.focalWell),document.activeElement.blur()},_setFocalWellRect:function(e){var t;if(this.disableAddDeleteWell){var i=this.locToAddress({r:e.row,c:e.col});this.addressAllowToEdit.indexOf(i)<0?(t=!1,this.setFieldsDisabled(!0)):(t=!0,this.setFieldsDisabled(!1))}else e&&(t=!0);if(t){var a=this._areaToRect(this._wellToArea(e));this.focalWellRect?(this.focalWellRect.top=a.top,this.focalWellRect.left=a.left,this.focalWellRect.width=a.width-2,this.focalWellRect.height=a.height-2):(this.focalWellRect=new n.Rect({width:a.width-2,height:a.height-2,left:a.left,top:a.top,fill:null,strokeWidth:2,stroke:"black",selectable:!1}),this.mainFabricCanvas.add(this.focalWellRect))}else this.mainFabricCanvas.remove(this.focalWellRect),this.focalWellRect=null},_setSelectedTiles:function(){var i=this.allSelectedObjects;this.allTiles.forEach(function(e){var t=0<=i.indexOf(e);e.highlight.visible=t})},_getSelectedWells:function(){var i=this;return this.allSelectedObjects.map(function(e){var t=i.engine.derivative[e.index];return t||(t=i.defaultWell),t})},_getCommonFields:function(e){if(e.length){for(var t=e[0],i=u.extend(!0,{},t),a=1;a<e.length;a++){var n=e[a];for(var l in i)if(Array.isArray(i[l])){for(var s=i[l],r=[],o=0;o<s.length;o++){var d=s[o];d&&"object"==typeof d?this.containsObject(d,n[l])&&r.push(d):0<=u.inArray(d,n[l])&&r.push(d)}i[l]=r}else n[l]&&"object"==typeof n[l]&&i[l]&&"object"==typeof i[l]?n[l].value===i[l].value&&n[l].unit===i[l].unit||delete i[l]:i[l]!=n[l]&&delete i[l]}return i}return{}},containsObject:function(n,e){var t=[];return!!e&&(e.forEach(function(i){var a=[];Object.keys(i).forEach(function(e){if(0<=Object.keys(n).indexOf(e)){var t=i[e];"object"==typeof t&&t?n[e]?a.push(t.unit===n[e].unit&&t.value===n[e].value):a.push(!1):a.push(t===n[e])}}),t.push(a.indexOf(!1)<0)}),0<=t.indexOf(!0))},_getCommonWell:function(e){if(e.length){for(var t=e[0],i=u.extend(!0,{},t),a=1;a<e.length;a++){var n=e[a];for(var l in i)if(Array.isArray(i[l])){for(var s=i[l],r=[],o=0;o<s.length;o++){var d=s[o];"object"==typeof s[o]?this.containsObject(d,n[l])&&r.push(d):0<=u.inArray(d,n[l])&&r.push(d)}i[l]=r}else n[l]&&"object"==typeof n[l]&&i[l]&&"object"==typeof i[l]?n[l].value===i[l].value&&n[l].unit===i[l].unit||(i[l]=null):i[l]!=n[l]&&(i[l]=null)}return i}return this.defaultWell},_getAllMultipleVal:function(e){this.multipleFieldList.forEach(function(i){if(e.length){var a={};e.forEach(function(e){var t=i.id;e[t]&&0<e[t].length&&e[t].forEach(function(e){"object"==typeof e?e[t]in a?a[e[t]]++:a[e[t]]=1:e in a?a[e]++:a[e]=1})}),i.allSelectedMultipleVal=a}else i.allSelectedMultipleVal=null})},decideSelectedFields:function(){var e=this._getSelectedWells();this._getAllMultipleVal(e),this.applyFieldWarning(e);var t=this._getCommonWell(e);this._addDataToTabFields(t)},getDifferentWellsVals:function(e){var t=[];for(var i in e)t.push(e[i]);var a={};if(1<t.length){var n=this._getCommonWell(t),l={};for(var s in e[0])l[s]=[];for(var r in t){var o={},d=t[r];for(var u in d){var c=n[u],f=d[u],h=null;if(Array.isArray(f)){h=[];for(var p=0;p<f.length;p++){var v=f[p];v?this.containsObject(v,c)||(h.push(v),this.containsObject(v,l[u])||l[u].push(v)):0<=c.indexOf(v)&&(h.push(v),0<=!l[u].indexOf(v)&&l[u].push(v))}}else f&&"object"==typeof f?c&&"object"==typeof c?f.value!==c.value&&f.unit!==c.unit&&(h=f,this.containsObject(f,l[u])||l[u].push(f)):(h=f,this.containsObject(f,l[u])||l[u].push(f)):f!==c&&(h=f,0<=!l[u].indexOf(f)&&l[u].push(f));o[u]=h}a[r]=o}for(var u in l)if(0===l[u].length)for(var r in a)delete a[r][u];return a}if(e[0]){var b={};for(var u in e[0]){f=e[0][u];Array.isArray(f)?0<f.length&&(b[u]=f):f&&(b[u]=f)}return{0:b}}},getWellSetAddressWithData:function(){var e=[],t=this.engine.derivative;for(var i in t)e.push(this.indexToAddress(i));return e}}}}(jQuery,fabric),(plateLayOutWidget=plateLayOutWidget||{}).assets=function(){return{_assets:{doImg:"✓",dontImg:"",warningImg:"⚠"}}};plateLayOutWidget=plateLayOutWidget||{};!function(i,e){plateLayOutWidget.interface=function(){return{_createInterface:function(){var e="<div></div>";this.container=this._createElement(e).addClass("plate-setup-wrapper"),this.topSection=this._createElement(e).addClass("plate-setup-top-section"),this.topLeft=this._createElement(e).addClass("plate-setup-top-left"),this.topRight=this._createElement(e).addClass("plate-setup-top-right"),this.overLayContainer=this._createElement(e).addClass("plate-setup-overlay-container"),this.canvasContainer=this._createElement(e).addClass("plate-setup-canvas-container"),this._createOverLay(),i(this.topLeft).append(this.overLayContainer),this._createCanvas(),i(this.topLeft).append(this.canvasContainer),i(this.topSection).append(this.topLeft),i(this.topSection).append(this.topRight),i(this.container).append(this.topSection),i(this.element).append(this.container),this._initiateFabricCanvas(),this._createTabAtRight(),this._createTabs(),this._placePresetTabs(),this._bottomScreen(),this._canvas(),this.bottomForFirstTime();var t=this;this._setShortcuts(),i(document.body).keyup(function(e){t._handleShortcuts(e)}),this._configureUndoRedoArray()},_createElement:function(e){return i(e)},_setShortcuts:function(){var t=this;window.addEventListener("cut",function(e){document.activeElement==document.body&&(t.copyCriteria(),t.clearCriteria(),e.preventDefault())}),window.addEventListener("copy",function(e){document.activeElement==document.body&&(t.copyCriteria(),e.preventDefault())}),window.addEventListener("paste",function(e){document.activeElement==document.body&&(t.pasteCriteria(),e.preventDefault())})},_handleShortcuts:function(e){document.activeElement===document.body&&(46==e.keyCode?(this.clearCriteria(),e.preventDefault()):(e.ctrlKey||e.metaKey)&&(90==e.keyCode?(e.shiftKey?this.redo():this.undo(),e.preventDefault()):89==e.keyCode&&(this.redo(),e.preventDefault())))}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(t,e){plateLayOutWidget.loadPlate=function(e){return{getPlates:function(e){var t={};for(var i in e.derivative){var a=e.derivative[i];t[i]=this.sanitizeWell(a)}var n=e.checkboxes||[],l=this.sanitizeAreas(e.selectedAreas,e.focalWell),s={derivative:t,checkboxes:n,selectedAreas:l.selectedAreas,focalWell:l.focalWell};this.setData(s)},sanitizeAreas:function(e,t){var i=this,a=this.dimensions.rows,n=this.dimensions.cols;if(e||(e=[]),e.length){var l=(e=e.map(function(e){return{minCol:i._coordIndex(Math.min(e.minCol,e.maxCol),n),minRow:i._coordIndex(Math.min(e.minRow,e.maxRow),a),maxCol:i._coordIndex(Math.max(e.minCol,e.maxCol),n),maxRow:i._coordIndex(Math.max(e.minRow,e.maxRow),a)}}))[e.length-1];t&&!this._wellInArea(t,l)&&(t=null),t||(t={row:l.minRow,col:l.minCol})}else t||(t={row:0,col:0}),e=[this._wellToArea(t)];return{selectedAreas:e,focalWell:t}},sanitizeWell:function(e){for(var t={},i=0;i<this.fieldList.length;i++){var a=this.fieldList[i];t[a.id]=a.parseValue(e[a.id])}return t},setData:function(e){this.engine.derivative=t.extend(!0,{},e.derivative),this.setCheckboxes(e.checkboxes),this.setSelection(e.selectedAreas,e.focalWell),this._colorMixer(),this.decideSelectedFields(),this.mainFabricCanvas.renderAll()}}}}(jQuery,fabric);var GET_PLATES="getPlates",IS_READ_ONLY="isReadOnly",IS_DISABLE_ADD_DELETE_WELL="isDisableAddDeleteWell",GET_SELECTED_OBJECT="getSelectedObject",SETSELECTEDWELL="setSelectedWell";plateLayOutWidget=plateLayOutWidget||{};jQuery,fabric,plateLayOutWidget.overlay=function(){return{_createOverLay:function(){var t=this;this.overLayTextContainer=this._createElement("<div></div>").addClass("plate-setup-overlay-text-container"),this.overLayTextContainer.text("Completion Percentage:"),this.overLayContainer.append(this.overLayTextContainer),this.overLayButtonContainer=this._createElement("<div></div>").addClass("plate-setup-overlay-button-container"),this.overLayContainer.append(this.overLayButtonContainer),this.clearCriteriaButton=this._createElement("<button />").addClass("plate-setup-button"),this.clearCriteriaButton.text("Clear"),this.overLayButtonContainer.append(this.clearCriteriaButton),this.clearCriteriaButton.click(function(e){t.clearCriteria()}),this.copyCriteriaButton=this._createElement("<button />").addClass("plate-setup-button"),this.copyCriteriaButton.text("Copy"),this.overLayButtonContainer.append(this.copyCriteriaButton),this.copyCriteriaButton.click(function(e){t.copyCriteria()}),this.pasteCriteriaButton=this._createElement("<button />").addClass("plate-setup-button"),this.pasteCriteriaButton.text("Paste"),this.overLayButtonContainer.append(this.pasteCriteriaButton),this.pasteCriteriaButton.click(function(e){t.pasteCriteria()}),this.undoButton=this._createElement("<button />").addClass("plate-setup-button"),this.undoButton.text("Undo"),this.overLayButtonContainer.append(this.undoButton),this.undoButton.click(function(e){t.undo()}),this.redoButton=this._createElement("<button />").addClass("plate-setup-button"),this.redoButton.text("Redo"),this.overLayButtonContainer.append(this.redoButton),this.redoButton.click(function(e){t.redo()})},clearCriteria:function(){if(this.allSelectedObjects){for(var e=this.allSelectedObjects.length,t=!1,i=0;i<e;i++){var a=this.allSelectedObjects[i];if(a.index in this.engine.derivative){if(this.emptyWellWithDefaultVal&&this.disableAddDeleteWell){var n=JSON.parse(JSON.stringify(this.defaultWell)),l=this.emptyWellWithDefaultVal;for(var s in l)s in n?(n[s]=l[s],this._applyFieldData(s,l[s])):console.log("Well does not contain key: "+s+", please contact support");this.engine.derivative[a.index]=n}else delete this.engine.derivative[a.index];t=!0}}t&&this.derivativeChange(),this._colorMixer(),this.decideSelectedFields()}else alert("Please select any well")},copyCriteria:function(){if(this.allSelectedObjects){var e=this._getSelectedWells();this.commonWell=this._getCommonFields(e)}else alert("Please select any well.")},pasteCriteria:function(){this.commonWell&&(this._addAllData(this.commonWell),this.decideSelectedFields(),this.mainFabricCanvas.renderAll())}}},$.widget("DNA.plateLayOut",{plateLayOutWidget:{},options:{value:0},allTiles:[],addressToLoc:function(e){var t=/^([A-Z]+)(\d+)$/.exec(e.trim().toUpperCase());if(t){for(var i,a=t[1],n=parseInt(t[2])-1,l=0;l<a.length;l++){var s=a.charCodeAt(l)-65;l?(i+=1,i*=26,i+=s):i=s}return{r:i,c:n}}throw e+" not a proper layout address"},locToIndex:function(e,i){if(i||(i=this.dimensions),e.r<0&&t,!(0<=e.r&&e.r<i.rows))throw"Row index "+(e.r+1)+" invalid";if(!(0<=e.c&&e.c<i.cols))throw"Column index "+(e.c+1)+" invalid";return e.r*i.cols+e.c},addressToIndex:function(e,t){var i=this.addressToLoc(e);return this.locToIndex(i,t)},_rowKey:function(e){var t=e%26,i=(e-t)/26,a=String.fromCharCode(65+t);return 0<i&&(a=String.fromCharCode(64+i)+a),a},indexToLoc:function(e,t){if(t||(t=this.dimensions),e>=t.rows*t.cols)throw"Index too high: "+e.toString(10);var i={};return i.c=e%t.cols,i.r=(e-i.c)/t.cols,i},locToAddress:function(e){return this._rowKey(e.r)+(e.c+1).toString(10)},indexToAddress:function(e,t){var i=this.indexToLoc(e,t);return this.locToAddress(i)},getDimensions:function(){return $.extend(!0,{},this.dimensions)},_create:function(){var e=parseInt(this.options.numRows||8),t=parseInt(this.options.numCols||12);this.dimensions={rows:e,cols:t},this.rowIndex=[];for(var i=0;i<e;i++)this.rowIndex.push(this._rowKey(i));for(var a in this.target=this.element[0].id?"#"+this.element[0].id:"."+this.element[0].className,this.options.readOnly&&this.isReadOnly(!0),plateLayOutWidget)$.extend(this,new plateLayOutWidget[a](this));return this.imgSrc=this.options.imgSrc||"assets",this._createInterface(),this._trigger("created",null,this),this},_init:function(){},addData:function(){alert("wow this is good")},getTextDerivative:function(e){var t={};this.fieldMap;for(var i in e){var a={},n={},l=e[i];for(var s in l)if(s in this.fieldMap){var r=this.fieldMap[s],o=r.parseText(l[s]);n[r.name]=o,a[s]=o}else n[s]=l[s],a[s]=l[s];t[i]={textVal:a,textFieldVal:n}}return t},getWellsDifferences:function(e){return this.getDifferentWellsVals(e)},setFieldsDisabled:function(t){this.fieldList.forEach(function(e){e.disabled(t)})},isReadOnly:function(e){this.readOnly=!!e,this.readOnlyHandler()},readOnlyHandler:function(){this.readOnly?(this.overLayButtonContainer.css("display","none"),$(".multiple-field-manage-delete-button").css("display","none"),this.setFieldsDisabled(!0)):(this.overLayButtonContainer.css("display","flex"),$(".multiple-field-manage-delete-button").css("display","none"),this.disableAddDeleteWell||this.setFieldsDisabled(!1))},disableAddDeleteWell:null,isDisableAddDeleteWell:function(e,t){e?(this.disableAddDeleteWell=!0,this.addressAllowToEdit=this.getWellSetAddressWithData(),this.actionPointer=0,this.undoRedoArray=[],this.undoRedoArray.push(this.createObject()),t&&(this.emptyWellWithDefaultVal=t)):(this.disableAddDeleteWell=!1,this.setFieldsDisabled(!1),this.emptyWellWithDefaultVal=null),this._fabricEvents()},getSelectedObject:function(){for(var e=[],t=0;t<this.allSelectedObjects.length;t++)e.push(this.allSelectedObjects[t].address);var i={},a=this.engine.derivative;for(var n in a){var l=this.indexToAddress(n);0<=e.indexOf(l)&&(i[l]=a[n])}return i},getSelectedIndex:function(){return this.allSelectedObjects.map(function(e){return that.addressToIndex(e.address)})},getSelectedAddress:function(){return this.allSelectedObjects.map(function(e){return e.address})},setSelectedWell:function(e){for(var t=[],i=999,a={},n=0;n<e.length;n++){var l=this.addressToIndex(e[n]),s=this.indexToLoc(l);t.push({minCol:s.c,minRow:s.r,maxCol:s.c,maxRow:s.r}),s.r<=i&&(i=s.r,s.r in a?a[s.r].push(s.c):a[s.r]=[s.c])}var r={row:i,col:Math.min.apply(null,a[i])};this.setSelection(t,r),this.decideSelectedFields(),this.mainFabricCanvas.renderAll()}});plateLayOutWidget=plateLayOutWidget||{};!function(s,e){plateLayOutWidget.preset=function(e){return{presets:[],_placePresetTabs:function(){var e=this.options.attributes.presets;if(e&&e.length){this.wellAttrContainer=this._createElement("<div></div>").addClass("plate-setup-well-attr-container").text("Checkbox presets"),this.tabContainer.append(this.wellAttrContainer),this.presetTabContainer=this._createElement("<div></div>").addClass("plate-setup-preset-container"),this.tabContainer.append(this.presetTabContainer);for(var t=0;t<e.length;t++){var i=e[t],a=this._createElement("<div></div>").addClass("plate-setup-prest-tab-div").text(i.title),n=this._createElement("<div></div>").addClass("plate-setup-prest-tab").data("preset",i.fields).append(a);this.presetTabContainer.append(n);var l=this;n.click(function(){var e=s(this);l._selectPreset(e)}),this.presets.push(n)}}},_clearPresetSelection:function(){for(var e=0;e<this.presets.length;e++){this.presets[e].removeClass("plate-setup-prest-tab-selected").addClass("plate-setup-prest-tab")}},_selectPreset:function(e){this.setCheckboxes(e.data("preset")),e.removeClass("plate-setup-prest-tab").addClass("plate-setup-prest-tab-selected")}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(a,e){plateLayOutWidget.tabs=function(){return{allTabs:[],defaultWell:{},allDataTabs:[],_createTabAtRight:function(){this.tabContainer=this._createElement("<div></div>").addClass("plate-setup-tab-container"),a(this.topRight).append(this.tabContainer)},_createTabs:function(){this.tabHead=this._createElement("<div></div>").addClass("plate-setup-tab-head"),a(this.tabContainer).append(this.tabHead);var e=this.options.attributes.tabs,i=this;e.forEach(function(e,t){i.allTabs[t]=i._createElement("<div></div>").addClass("plate-setup-tab"),a(i.allTabs[t]).data("index",t).text(e.name),a(i.allTabs[t]).click(function(){i._tabClickHandler(this)}),a(i.tabHead).append(i.allTabs[t])}),this.tabDataContainer=this._createElement("<div></div>").addClass("plate-setup-tab-data-container"),a(this.tabContainer).append(this.tabDataContainer),this._addDataTabs(e),a(this.allTabs[0]).click(),this._addTabData()},_tabClickHandler:function(e){if(this.selectedTab){a(this.selectedTab).removeClass("plate-setup-tab-selected").addClass("plate-setup-tab");var t=a(this.selectedTab).data("index");a(this.allDataTabs[t]).css("z-index",0),this.readOnlyHandler()}a(e).addClass("plate-setup-tab-selected"),this.selectedTab=e;var i=a(e).data("index");a(this.allDataTabs[i]).css("z-index",1e3)},_addDataTabs:function(e){var t=0;for(var i in e)this.allDataTabs[t++]=this._createElement("<div></div>").addClass("plate-setup-data-div").css("z-index",0),a(this.tabDataContainer).append(this.allDataTabs[t-1])}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};!function(i,e){plateLayOutWidget.undoRedoManager=function(e){return{undoRedoArray:[],actionPointer:null,addToUndoRedo:function(e){if(null!=this.actionPointer){var t=this.actionPointer+1;t<this.undoRedoArray.length&&this.undoRedoArray.splice(t,this.undoRedoArray.length-t)}this.actionPointer=null,this.undoRedoArray.push(i.extend(!0,{},e))},_configureUndoRedoArray:function(){this.undoRedoArray=[],this.actionPointer=null,this.undoRedoArray.push(i.extend({},{checkboxes:[],derivative:{},selectedAreas:[{minRow:0,minCol:0,maxRow:0,maxCol:0}],focalWell:{row:0,col:0}}))},undo:function(){return console.log("undo"),this.shiftUndoRedo(-1)},redo:function(){return console.log("redo"),this.shiftUndoRedo(1)},shiftUndoRedo:function(e){var t=this.actionPointer;return null==t&&(t=this.undoRedoArray.length-1),t+=e,this.setUndoRedo(t)},setUndoRedo:function(e){return!(e<0)&&(!(e>=this.undoRedoArray.length)&&(this.undoRedoActive=!0,this.setData(this.undoRedoArray[e]),this.actionPointer=e,this.undoRedoActive=!1,this.derivativeChange(),!0))}}}}(jQuery,fabric);plateLayOutWidget=plateLayOutWidget||{};jQuery,fabric,plateLayOutWidget.wellArea=function(e){return{_areasToTiles:function(e){var l=this.dimensions.cols,s=this;return e.reduce(function(e,t){if(t)for(var i=t.minRow;i<=t.maxRow;i++)for(var a=t.minCol;a<=t.maxCol;a++){var n=s.allTiles[a+l*i];e.indexOf(n)<0&&(s.disableAddDeleteWell?0<=s.addressAllowToEdit.indexOf(n.address)&&e.push(n):e.push(n))}return e},[])},_encodeArea:function(e){return e.minRow==e.maxRow&&e.minCol==e.maxCol?this.rowIndex[e.minRow]+e.minCol.toString(10):this.rowIndex[e.minRow]+e.minCol.toString(10)+":"+this.rowIndex[e.maxRow]+e.maxCol.toString(10)},_encodeAreas:function(e){var t=this;return e.map(function(e){return t._encodeArea(e)}).join(",")},_decodeWell:function(e){var t,i=new RegExp("^\\s*("+this.rowIndex.join("|")+")(\\d+)\\s*$");if(t=e.match(i)){var a=this.rowIndex.indexOf(t[1]);if(0<=a)return{row:a,col:parseInt(t[2])-1}}if(t=e.match(/^\s*R(\d+)C(\d+)\s*$/i))return{row:parseInt(t[1])-1,col:parseInt(t[2])-1};throw"Invalid well address: "+e},_decodeArea:function(e){var t=this,i=e.split(":").map(function(e){return t._decodeWell(e)});if(1==i.length)return{minRow:i[0].row,minCol:i[0].col,maxRow:i[0].row,maxCol:i[0].col};if(2!=i.length)throw"Invalid address: "+e;return Math.min(i[0].row,i[1].row),{minRow:Math.min(i[0].row,i[1].row),minCol:Math.min(i[0].col,i[1].col),maxRow:Math.max(i[0].row,i[1].row),maxCol:Math.max(i[0].col,i[1].col)}},_decodeAreas:function(e){var t=this;return e.split(",").map(function(e){return t._decodeArea(e)})},_wellToArea:function(e){return{minCol:e.col,minRow:e.row,maxCol:e.col,maxRow:e.row}},_wellInArea:function(e,t){return e.row>=t.minRow&&e.row<=t.maxRow&&e.col>=t.minCol&&e.col<=t.maxCol},_coordsToRect:function(e,t){var i=Math.min(e.x,t.x);return{top:Math.min(e.y,t.y),left:i,height:Math.abs(t.y-e.y),width:Math.abs(t.x-e.x)}},_coordIndex:function(e,t){return e<0?0:t<=e?t-1:Math.floor(e)},_coordsToWell:function(e){var t=this.dimensions.cols,i=this.dimensions.rows,a=this.sizes.spacing,n=this.sizes.label_spacing,l=(e.x-n)/a,s=(e.y-n)/a;return{row:this._coordIndex(s,i),col:this._coordIndex(l,t)}},_wellToCoords:function(e,t){var i=this.sizes.spacing,a=this.sizes.label_spacing,n=e.col*i+a,l=e.row*i+a;if(t){var s=i/2;n+=s,l+=s}return{x:n,y:l}},_areaToRect:function(e){var t=e.maxRow-e.minRow+1,i=e.maxCol-e.minCol+1,a=this.sizes.spacing,n=this.sizes.label_spacing;return{top:e.minRow*a+n,left:e.minCol*a+n,height:t*a,width:i*a}},_rectToArea:function(e){var t=this.dimensions.rows,i=this.dimensions.cols,a=this.sizes.spacing,n=this.sizes.label_spacing,l=(e.left-n)/a,s=(e.top-n)/a,r=e.height/a,o=l+e.width/a,d=s+r;return o<0&&(o=i),i<=l&&(l=0),d<0&&(d=t),s<=0&&(s=0),{minCol:this._coordIndex(l,i),minRow:this._coordIndex(s,t),maxCol:this._coordIndex(o,i),maxRow:this._coordIndex(d,t)}}}}; -//# sourceMappingURL=plate-map.min.js.map \ No newline at end of file diff --git a/dist/js/plate-map.min.js.map b/dist/js/plate-map.min.js.map deleted file mode 100644 index da1b0dd..0000000 --- a/dist/js/plate-map.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["add-data-on-change.js","add-data-to-tabs.js","add-tab-data.js","add-warning-msg.js","bottom-table.js","canvas.js","check-box.js","color-manager.js","create-canvas-elements.js","create-field.js","engine.js","fabric-events.js","image_assets.js","interface.js","load-plate.js","main.js","overlay.js","plate-layout.js","preset.js","tabs.js","undo-redo-manager.js","well-area.js"],"names":["plateLayOutWidget","$","fabric","addDataOnChange","_addAllData","data","this","allSelectedObjects","noOfSelectedObjects","length","wells","objectIndex","well","tile","index","engine","derivative","extend","defaultWell","processedData","processWellData","wellEmpty","emptyWellWithDefaultVal","disableAddDeleteWell","wellCopy","JSON","parse","stringify","defaultValue","key","_applyFieldData","_getAllMultipleVal","applyFieldWarning","_colorMixer","derivativeChange","newData","curWell","wellList","id","v","undefined","multi","curData","preData","newDt","_getMultiData","push","fieldId","addNew","added","removed","value","add","listIdx","toString","map","val","subFieldId","indexOf","removeIndex","removeListIndex","newPreData","idx","parseInt","undoRedoActive","createObject","addToUndoRedo","searchAndStack","applyColors","mainFabricCanvas","renderAll","_trigger","checkboxes","globalSelectedAttributes","slice","selectedAreas","focalWell","requiredField","jQuery","addDataToFields","_addDataToTabFields","values","fieldMap","setValue","addTabData","fieldList","autoId","_addTabData","tabData","options","attributes","tabs","that","multiplexFieldArray","forEach","tab","tabPointer","tabFields","fieldArray","field","field_val","console","log","type","_makeMultiplexField","_makeRegularField","allDataTabs","multipleFieldList","_makeSubField","wrapperDiv","_createElement","addClass","wrapperDivLeftSide","wrapperDivRightSide","nameContainer","text","name","fieldContainer","append","root","required","checkbox","_addCheckBox","_createField","onChange","getValue","subFieldList","requiredSubField","subFieldKey","multiplexFields","subFieldData","subField","multiplexId","subFields","subfield","mainMultiplexField","mainRefField","curId","singleSelectValue","curVal","returnVal","_changeMultiFieldValue","curDataLs","detailData","input","select2","i","addWarningMsg","fieldWarningMsg","include","imgId","img","html","_assets","warningImg","attr","find","prepend","popText","hover","e","style","display","hide","remove","removeWarningMsg","fieldData","applyMultiplexSubFieldColor","Array","bottomTable","_bottomScreen","bottomContainer","bottomTableContainer","container","addBottomTableHeadings","bottomRow","singleField","empty","rowCounter","adjustFieldWidth","tileAttrText","getText","addBottomTableRow","color","singleStack","modelTile","allTiles","row","plateIdDiv","numberText","click","evt","addressToSelect","addressIdx","indexToAddress","ctrlKey","getSelectedAddress","setSelectedWell","selectedAddress","colorPairs","colorStops","css","dataDiv","bottomForFirstTime","createExportButton","downloadCSV","csv","filename","csvFile","downloadLink","Blob","document","createElement","download","href","window","URL","createObjectURL","body","appendChild","exportData","format","rows","querySelectorAll","colorLocMap","colorLocIdxMap","stackUpWithColor","dim","getDimensions","colorIdx","locIdx","cols","j","innerText","replace","loc","join","overlayContainer","descriptionDiv","buttonContainer","exportButton","resetExportText","classList","setTimeout","clipboardButton","clipboard","ClipboardJS","get","resetClipboardText","on","canvas","allPreviouslySelectedObjects","colorPointer","goldenRatio","_createCanvas","normalCanvas","canvasContainer","_initiateFabricCanvas","w","width","h","height","_setCanvasArea","Canvas","backgroundColor","selection","stateful","hoverCursor","renderOnAddRemove","setWidth","setHeight","checkBox","checkImage","dontImg","_applyCheckboxHandler","checkBoxImage","machineClick","changes","changeCheckboxes","changeSubFieldsCheckboxes","subFieldToInclude","clicked","Boolean","doImg","gsa","multiplexCheckedSubField","globalSelectedMultiplexSubfield","_clearPresetSelection","setSubFieldCheckboxes","fieldIds","setCheckboxes","colorManager","createCanvasElements","scaleFactor","baseSizes","spacing","tile_radius","center_radius_complete","center_radius_incomplete","label_size","label_spacing","text_size","stroke","gap","Math","min","dimensions","sizes","prop","_canvas","_fixRowAndColumn","_putCircles","d1","d2","fontSize","top","left","tempFabricText","IText","fill","originX","originY","fontFamily","selectable","fontWeight","rowIndex","tileCounter","col","_createTile","background","highlight","circle","circleCenter","circleText","_addLargeRectangleOverlay","_fabricEvents","visible","colorIndex","address","Circle","radius","hasControls","hasBorders","lockMovementX","lockMovementY","evented","setGradient","x1","x2","y1","y2","r1","r2","0","1","Rect","strokeWidth","lockScalingX","lockScalingY","setTileComplete","complete","setTileVisible","setTileColor","stackPointer","String","overLay","opacity","createField","_createTextField","_createNumericField","_createSelectField","_createMultiSelectField","_createBooleanField","_createMultiplexField","parseValue","trim","disabled","bool","parseText","generated","_createOpts","config","opts","allowClear","placeholder","minimumResultsForSearch","query","delay","_debounce","optMap","opt","setOpts","multiple","allOpts","selectedVal","curOpts","multiOnChange","_createDeleteButton","units","defaultUnit","unitInput","hasUnits","unitText","selected","unit","o","setUnitOpts","newUnits","curUnit","cleanUnit","newOpts","isPlainObject","parseRegularValue","parseUnit","getRegularValue","isNaN","getUnit","hasMultiplexUnit","unitTypeKey","unitMap","setUnit","setRegularValue","Number","toLowerCase","u","getRegularText","textVal","removeClass","tval","fval","initSelection","element","callback","nameContainer1","fieldContainer1","singleSelect","appendTo","setSingleSelectOptions","selected_v","singleSelectChange","updateSubFieldUnitOpts","curSubField","readOnlyHandler","newSubFieldValue","subFieldName","multiselectSetValue","multiselectValues","newOptions","valMap","hasOwnProperty","unitOptions","curIds","curOpt","newMultiplexVal","selectList","newVal","selectId","checkedSubfields","valIdx","subV","subText","optId","x","checkMultiplexCompletion","valList","valCount","completionPct","getSubfieldStatus","vals","req","subFieldWarningMap","warningStatus","multiplexVals","multiplexIdx","updateSubFieldWarningMap","mainFieldStatus","warningText","mainFieldWarning","parseMainFieldVal","_deleteDialog","valToRemove","allSelectedMultipleVal","Object","keys","dialogDiv","killDialog","dialogContent","tableArea","buttonRow","table","_deleteDialogTable","readOnly","deleteCheckedButton","each","decideSelectedFields","cancelButton","show","onclick","event","target","colName","thead","tbody","tr","deleteButton","THIS","isArray","derivativeJson","wellData","selectedSubFields","curMultiplexVals","isEmptyObject","k","parseFloat","sort","a","b","refDerivativeIndex","referenceDerivative","arr","wholeNoTiles","wholePercentage","tileIndex","completion","checkCompletion","floor","overLayTextContainer","multiplexStatus","fabricEvents","colorToIndex","startCoords","y","_clickCoords","rect","getBoundingClientRect","clientX","clientY","getPlates","selecting","coords","areas","_wellToCoords","_coordsToRect","_coordsToWell","shiftKey","_rectToArea","setSelection","endCoords","area","_areasToTiles","_setSelectedTiles","_setFocalWellRect","activeElement","blur","flag","locToAddress","r","c","addressAllowToEdit","setFieldsDisabled","_areaToRect","_wellToArea","focalWellRect","selectedTiles","_getSelectedWells","_getCommonFields","referenceWell","referenceFields","fields","refArr","agrArr","containsObject","inArray","obj","list","equality","evaluate","listKey","_getCommonWell","multiplexField","curMultipleVal","multipleVal","getDifferentWellsVals","wellsHash","wellId","differentWellsVals","commonWell","allFieldVal","fieldIdx","wellIdx","diffWellVal","curWellData","commonVal","curMultiVal","getWellSetAddressWithData","assets","interface","_createInterface","divIdentifier","topSection","topLeft","topRight","overLayContainer","_createOverLay","_createTabAtRight","_createTabs","_placePresetTabs","_setShortcuts","keyup","_handleShortcuts","_configureUndoRedoArray","addEventListener","copyCriteria","clearCriteria","preventDefault","pasteCriteria","keyCode","metaKey","redo","undo","loadPlate","sanitizeWell","sanitizeAreas","sanitized","setData","minCol","_coordIndex","maxCol","minRow","maxRow","max","_wellInArea","newWell","GET_PLATES","IS_READ_ONLY","IS_DISABLE_ADD_DELETE_WELL","GET_SELECTED_OBJECT","SETSELECTEDWELL","overlay","overLayButtonContainer","clearCriteriaButton","copyCriteriaButton","pasteCriteriaButton","undoButton","redoButton","hasWellUpdate","alert","widget","addressToLoc","layoutAddress","m","exec","toUpperCase","row_v","charCodeAt","locToIndex","t","addressToIndex","_rowKey","c1","c2","code","fromCharCode","indexToLoc","_create","numRows","numCols","component","className","isReadOnly","imgSrc","_init","addData","getTextDerivative","wellsData","textDerivative","textValWell","textFieldIdWell","textFieldVal","getWellsDifferences","isDisableAddDeleteWell","column_with_default_val","actionPointer","undoRedoArray","getSelectedObject","selectedObjects","getSelectedIndex","selectedObj","addressList","locMap","apply","preset","me","presets","wellAttrContainer","tabContainer","presetTabContainer","divText","title","presetButton","_selectPreset","allTabs","tabHead","tabIndex","_tabClickHandler","tabDataContainer","_addDataTabs","clickedTab","selectedTab","previouslyClickedTabIndex","clickedTabIndex","undoRedoManager","splice","shiftUndoRedo","pointerDiff","pointer","setUndoRedo","wellArea","reduce","tiles","_encodeArea","_encodeAreas","_decodeWell","wellAddress","match","adRx","RegExp","_decodeArea","areaAddress","split","_decodeAreas","areasAddress","abs","count","coord","center","hw","right","bottom"],"mappings":"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","file":"plate-map.min.js","sourcesContent":["var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.addDataOnChange = function() {\n // This object is invoked when something in the tab fields change\n return {\n\n _addAllData: function(data) {\n // Method to add data when something changes in the tabs. Its going to be tricky , just starting.\n if (this.allSelectedObjects) {\n var noOfSelectedObjects = this.allSelectedObjects.length;\n var wells = [];\n for (var objectIndex = 0; objectIndex < noOfSelectedObjects; objectIndex++) {\n var tile = this.allSelectedObjects[objectIndex];\n var well;\n if (tile.index in this.engine.derivative) {\n well = this.engine.derivative[tile.index];\n } else {\n well = $.extend(true, {}, this.defaultWell); \n this.engine.derivative[tile.index] = well; \n }\n var processedData = this.processWellData(data, well, noOfSelectedObjects, wells);\n wells = processedData.wells;\n well = processedData.well;\n var empty = this.engine.wellEmpty(well);\n if (empty) {\n if (this.emptyWellWithDefaultVal && this.disableAddDeleteWell) {\n var wellCopy = JSON.parse(JSON.stringify(well));\n var defaultValue = this.emptyWellWithDefaultVal;\n for (var key in defaultValue){\n if (key in wellCopy){\n wellCopy[key] = defaultValue[key];\n this._applyFieldData(key, defaultValue[key]);\n }\n }\n this.engine.derivative[tile.index] = wellCopy;\n } else {\n delete this.engine.derivative[tile.index];\n }\n }\n }\n }\n // update multiplex remove all field\n this._getAllMultipleVal(wells);\n this.applyFieldWarning(wells);\n // create well when default field is sent for the cases when user delete all fields during disabledNewDeleteWell mode\n this._colorMixer();\n this.derivativeChange();\n },\n\n processWellData: function(newData, curWell, noOfSelectedObjects, wellList) {\n\n if (!wellList){\n wellList = [];\n }\n for (var id in newData) {\n var v;\n if (newData[id] !== undefined && newData[id] !== null ) {\n if (newData[id].multi){\n var curData = newData[id];\n var preData = curWell[id];\n var newDt = this._getMultiData(preData, curData, id, noOfSelectedObjects);\n // need to replace newData\n v = JSON.parse(JSON.stringify(newDt));\n } else {\n v = JSON.parse(JSON.stringify(newData[id]));\n }\n } else {\n v = JSON.parse(JSON.stringify(newData[id]));\n }\n curWell[id] = v;\n wellList.push(curWell);\n }\n\n return {\n well: curWell,\n wells: wellList\n }\n },\n\n _getMultiData: function(preData, curData, fieldId, noOfSelectedObjects) {\n var addNew = curData.added;\n var removed = curData.removed;\n if (addNew) {\n if (preData){\n if (addNew.value) {\n var add = true;\n for (var listIdx in preData) {\n var multiplexData = preData[listIdx];\n // for cases when the add new data exist in well\n if (multiplexData[fieldId].toString() === addNew.id.toString()) {\n add = false;\n // update subfield value\n preData = preData.map(function(val) {\n if (val[fieldId].toString() === addNew.id.toString()) {\n for (var subFieldId in val) {\n // over write previous data if only one well is selected\n if (subFieldId in addNew.value && subFieldId !== fieldId){\n if (noOfSelectedObjects === 1) {\n val[subFieldId] = addNew.value[subFieldId];\n } else if (addNew.value[subFieldId]) {\n val[subFieldId] = addNew.value[subFieldId];\n }\n }\n }\n }\n return val;\n })\n }\n }\n if (add) {\n preData.push(addNew.value);\n }\n } else if (preData.indexOf(addNew) < 0) {\n preData.push(addNew);\n }\n } else {\n preData = [];\n if (addNew.value) {\n preData.push(addNew.value);\n } else if (addNew){\n preData.push(addNew);\n }\n }\n }\n\n var removeListIndex = function(preData, removeIndex) {\n var newPreData = [];\n for (var idx in preData) {\n if (parseInt(idx) !== parseInt(removeIndex)){\n newPreData.push(preData[idx]);\n }\n }\n return newPreData;\n };\n\n if (removed) {\n var removeIndex;\n // for multiplex field\n if (removed.value) {\n for (var listIdx in preData) {\n var multiplexData = preData[listIdx];\n if (multiplexData[fieldId].toString() === removed.id.toString()) {\n removeIndex = listIdx;\n }\n }\n // remove nested element\n preData = removeListIndex(preData, removeIndex);\n } else {\n if (preData){\n removeIndex = preData.indexOf(removed);\n if (removeIndex >= 0) {\n preData = removeListIndex(preData, removeIndex);\n }\n }\n }\n }\n if (preData && (preData.length == 0)) {\n preData = null; \n }\n return preData\n },\n\n _colorMixer: function() {\n if (!this.undoRedoActive) {\n var data = this.createObject();\n this.addToUndoRedo(data);\n }\n this.engine.searchAndStack(); \n this.engine.applyColors();\n this.mainFabricCanvas.renderAll();\n },\n\n derivativeChange: function(){\n this._trigger(\"updateWells\", null, this.createObject());\n },\n\n createObject: function() {\n var derivative = $.extend(true, {}, this.engine.derivative); \n var checkboxes = this.globalSelectedAttributes.slice(); \n var selectedAreas = this.selectedAreas.slice(); \n var focalWell = this.focalWell;\n\n return {\n \"derivative\": derivative,\n \"checkboxes\": checkboxes,\n \"selectedAreas\": selectedAreas,\n \"focalWell\": focalWell,\n \"requiredField\": this.requiredField\n };\n }\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.addDataToFields = function() {\n\n return {\n\n _addDataToTabFields: function(values) {\n // Configure how data is added to tab fields\n for (var id in values) {\n this._applyFieldData(id, values[id]);\n }\n },\n\n _applyFieldData: function(id, v) {\n this.fieldMap[id].setValue(v); \n }\n }\n }\n})(jQuery, fabric)","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.addTabData = function() {\n\n return {\n\n fieldList: [], \n fieldMap: {},\n autoId: 1,\n\n _addTabData: function() {\n // Here we may need more changes because attributes format likely to change\n var tabData = this.options.attributes.tabs;\n var that = this;\n this.requiredField = [];\n var multiplexFieldArray = [];\n tabData.forEach(function (tab, tabPointer) {\n if (tab[\"fields\"]) {\n var tabFields = tab[\"fields\"];\n var fieldArray = [];\n var fieldArrayIndex = 0;\n // Now we look for fields in the json\n for (var field in tabFields) {\n var data = tabFields[field];\n\n if (!data.id) {\n data.id = \"Auto\" + that.autoId++;\n console.log(\"Field autoassigned id \" + data.id);\n }\n if (!data.type) {\n data.type = \"text\";\n console.log(\"Field \" + data.id + \" autoassigned type \" + data.type);\n }\n\n var field_val;\n if (data.type === \"multiplex\") {\n field_val = that._makeMultiplexField(data, tabPointer, fieldArray);\n multiplexFieldArray.push(field_val);\n } else {\n field_val = that._makeRegularField(data, tabPointer, fieldArray, true);\n if (data.type === \"multiselect\") {\n multiplexFieldArray.push(field_val);\n }\n };\n }\n\n that.allDataTabs[tabPointer][\"fields\"] = fieldArray;\n } else {\n console.log(\"unknown format in field initialization\");\n }\n });\n that.multipleFieldList = multiplexFieldArray;\n },\n\n _makeSubField: function (data, tabPointer, fieldArray) {\n var that = this;\n if (!data.id) {\n data.id = \"Auto\" + that.autoId++;\n console.log(\"Field autoassigned id \" + data.id);\n }\n if (!data.type) {\n data.type = \"text\";\n console.log(\"Field \" + data.id + \" autoassigned type \" + data.type);\n }\n var wrapperDiv = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-default-field\");\n var wrapperDivLeftSide = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-left-side\");\n var wrapperDivRightSide = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-right-side\");\n var nameContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-name\").text(data.name);\n var fieldContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-container\");\n\n $(wrapperDivRightSide).append(nameContainer);\n $(wrapperDivRightSide).append(fieldContainer);\n $(wrapperDiv).append(wrapperDivLeftSide);\n $(wrapperDiv).append(wrapperDivRightSide);\n $(that.allDataTabs[tabPointer]).append(wrapperDiv);\n\n var field = {\n id: data.id,\n name: data.name,\n root: wrapperDiv,\n data: data,\n required: data.required || false\n };\n\n fieldArray.push(field);\n that.fieldMap[data.id] = field;\n\n return field;\n },\n\n _makeRegularField: function (data, tabPointer, fieldArray, checkbox){\n var that = this;\n var wrapperDiv = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-default-field\");\n var wrapperDivLeftSide = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-left-side\");\n var wrapperDivRightSide = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-right-side \");\n var nameContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-name\").text(data.name);\n var fieldContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-container\");\n\n wrapperDivRightSide.append(nameContainer);\n wrapperDivRightSide.append(fieldContainer);\n wrapperDiv.append(wrapperDivLeftSide);\n wrapperDiv.append(wrapperDivRightSide);\n that.allDataTabs[tabPointer].append(wrapperDiv);\n\n var field = {\n id: data.id,\n name: data.name,\n root: wrapperDiv,\n data: data,\n required: data.required\n };\n\n if (field.required) {\n that.requiredField.push(field.id);\n }\n\n fieldArray.push(field);\n that.fieldList.push(field);\n that.fieldMap[field.id] = field;\n\n // Adding checkbox\n if (checkbox) {\n that._addCheckBox(field);\n }\n that._createField(field);\n\n field.onChange = function () {\n var v = field.getValue();\n var data = {};\n data[field.id] = v;\n that._addAllData(data);\n };\n return field;\n },\n\n _makeMultiplexField: function (data, tabPointer, fieldArray) {\n var that = this;\n var wrapperDiv = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-default-field\");\n var wrapperDivLeftSide = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-left-side\");\n var wrapperDivRightSide = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-right-side \");\n var nameContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-name\").text(data.name);\n var fieldContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-container\");\n\n wrapperDivRightSide.append(nameContainer);\n wrapperDivRightSide.append(fieldContainer);\n wrapperDiv.append(wrapperDivLeftSide);\n wrapperDiv.append(wrapperDivRightSide);\n that.allDataTabs[tabPointer].append(wrapperDiv);\n\n var field = {\n id: data.id,\n name: data.name,\n root: wrapperDiv,\n data: data,\n required: data.required\n };\n\n fieldArray.push(field);\n that.fieldList.push(field);\n that.fieldMap[data.id] = field;\n\n var subFieldList = [];\n //create subfields\n var requiredSubField = [];\n for (var subFieldKey in data.multiplexFields) {\n var subFieldData = data.multiplexFields[subFieldKey];\n var subField = that._makeSubField(subFieldData, tabPointer, fieldArray);\n subFieldList.push(subField);\n\n // stores required subField\n if (subFieldData.required) {\n requiredSubField.push(subField.id);\n }\n }\n\n //store required field\n if (field.required || requiredSubField.length) {\n this.requiredField.push ({\n multiplexId: field.id,\n subFields: requiredSubField\n });\n }\n\n field.subFieldList = subFieldList;\n that._createField(field);\n that._addCheckBox(field);\n\n subFieldList.forEach(function (subfield) {\n subfield.mainMultiplexField = field;\n fieldArray.push(subfield);\n that._createField(subfield);\n that._addCheckBox(subfield);\n delete that.defaultWell[subfield.id];\n // overwrite subField setvalue\n subfield.onChange = function () {\n var v = subfield.getValue();\n var mainRefField = subfield.mainMultiplexField;\n var curId = mainRefField.singleSelectValue();\n //var curDataLs = mainRefField.detailData;\n var curVal = {};\n curVal[mainRefField.id] = curId;\n //append subfields\n curVal[subfield.id] = v;\n var returnVal = {\n id: curId,\n value: curVal\n };\n\n field._changeMultiFieldValue(returnVal, null);\n var curDataLs = mainRefField.detailData;\n if (curDataLs !== null) {\n curId = mainRefField.singleSelectValue(); \n curDataLs = curDataLs.map(function(curData) {\n if (curData[mainRefField.id] === curId) {\n curData[subfield.id] = v;\n }\n return curData;\n });\n }\n mainRefField.detailData = curDataLs;\n };\n\n });\n\n field.getValue = function(){\n var v = field.input.select2('data');\n if (v.length) {\n return v.map(function (i) {\n return i.id;\n });\n }\n return null;\n };\n\n return field;\n }\n }\n }\n\n})(jQuery, fabric);\n","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.addWarningMsg = function () {\n // For those check boxes associated with every field in the tab\n return {\n fieldWarningMsg: function (field, text, include) {\n var that = this;\n var imgId = \"fieldWarning\" + field.id;\n var img = $(\"<span>\").html(that._assets.warningImg).attr(\"id\", imgId).addClass(\"plate-field-warning-image\");\n //field.root.find(\".plate-setup-tab-name\").append('<img id=\"theImg\" src=\"theImg.png\" />')\n if (include) {\n if (field.root.find(\"#\" + imgId).length <= 0){\n field.root.find(\".plate-setup-tab-name\").text(\" \" + field.name);\n field.root.find(\".plate-setup-tab-name\").prepend(img);\n\n var popText = $(\"<div/>\").addClass(\"pop-out-text\");\n popText.text(text);\n field.root.find(\".plate-setup-tab-name\").append(popText);\n\n $(\"#\" + imgId).hover(function (e) {\n popText[0].style.display = 'flex';\n }, function () {\n popText.hide();\n });\n }\n\n\n } else {\n if (field.root.find(\"#\" + imgId).length > 0) {\n field.root.find(\".plate-setup-tab-name\").text(field.name);\n $(\"#\" + imgId).remove();\n }\n }\n },\n\n removeWarningMsg: function (field, text, include) {\n var that = this;\n var imgId = \"fieldWarning\" + field.id;\n var img = $(\"<span>\").html(that._assets.warningImg).attr(\"id\", imgId).addClass(\"plate-field-warning-image\");\n //field.root.find(\".plate-setup-tab-name\").append('<img id=\"theImg\" src=\"theImg.png\" />')\n if (include) {\n field.root.find(\".plate-setup-tab-name\").append(img);\n\n var popText = $(\"<div/>\").addClass(\"pop-out-text\");\n popText.text(text);\n field.root.find(\".plate-setup-tab-name\").append(popText);\n\n $(\"#\" + imgId).hover(function (e) {\n popText[0].style.display = 'inline-block';\n }, function () {\n popText.hide();\n });\n\n } else {\n $(\"#\" + imgId).remove();\n if (field.root.find(\"#\" + imgId).length > 0) {\n //field.root.find(\".plate-setup-tab-name\").remove(img);\n $(\"#\" + imgId).remove();\n }\n }\n },\n\n applyFieldWarning: function(wells) {\n var that = this;\n var req = 0;\n var fill = 0;\n var fieldData = {};\n that.fieldList.forEach(function(field){\n fieldData[field.id] = [];\n });\n wells.forEach(function(well){\n if (!that.engine.wellEmpty(well)){\n for (var fieldId in fieldData) {\n if (fieldId in well) {\n fieldData[fieldId].push(well[fieldId]);\n } else {\n fieldData[fieldId].push(null);\n }\n }\n }\n });\n for (var i = 0; i < that.fieldList.length; i++) {\n var field = that.fieldList[i];\n if (field.applyMultiplexSubFieldColor){\n field.applyMultiplexSubFieldColor(fieldData[field.id]);\n } else {\n if (field.required) {\n var include = false;\n fieldData[field.id].forEach(function(val){\n // for multiselect\n if (val instanceof Array) {\n if (val.length === 0) {\n include = true;\n }\n } else {\n if (val === null) {\n include = true;\n }\n }\n });\n //field.root.find(\".plate-setup-tab-name\").css(\"background\", color);\n that.fieldWarningMsg(field, \"required field\", include);\n }\n }\n }\n }\n }\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.bottomTable = function() {\n // for bottom table\n return {\n _bottomScreen: function() {\n this.bottomContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-bottom-container\");\n this.bottomTableContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-bottom-table-container\");\n this.bottomTable = this._createElement(\"<table></table>\").addClass(\"plate-setup-bottom-table\");\n this.bottomTableContainer.append(this.bottomTable);\n this.bottomContainer.append(this.bottomTableContainer);\n this.container.append(this.bottomContainer);\n },\n\n addBottomTableHeadings: function() {\n\n this.bottomRow = this._createElement(\"<tr></tr>\");\n\n var singleField = this._createElement(\"<th></th>\")\n .text(\"Group\");\n this.bottomRow.prepend(singleField);\n // Now we append all the captions at the place.\n this.bottomTable.empty();\n this.bottomTable.append(this.bottomRow);\n\n this.rowCounter = 1;\n\n for (var i = 0; i < this.globalSelectedAttributes.length; i++) {\n var attr = this.globalSelectedAttributes[i];\n var field = this.fieldMap[attr];\n var singleField = this._createElement(\"<th></th>\").text(field.name);\n this.bottomRow.append(singleField);\n this.rowCounter = this.rowCounter + 1;\n }\n\n this.adjustFieldWidth(this.bottomRow);\n },\n\n tileAttrText: function(tile, attr) {\n var well = this.engine.derivative[tile.index];\n var field = this.fieldMap[attr];\n return field.getText(well[attr]);\n },\n\n addBottomTableRow: function(color, singleStack) {\n var that = this;\n var modelTile = this.allTiles[singleStack[0]];\n var row = this._createElement(\"<tr></tr>\");\n var plateIdDiv = this._createElement(\"<td></td>\").addClass(\"plate-setup-bottom-id\");\n var numberText = this._createElement(\"<button/>\");\n numberText.addClass(\"plate-setup-color-text\");\n numberText.text(color);\n plateIdDiv.append(numberText);\n\n numberText.click(function(evt){\n var addressToSelect = singleStack.map(function(addressIdx){\n return that.indexToAddress(addressIdx)\n });\n if (evt.ctrlKey) {\n that.getSelectedAddress().forEach(function(val){\n if (addressToSelect.indexOf(val) < 0){\n addressToSelect.push(val);\n }\n })\n }\n that.setSelectedWell(addressToSelect);\n that._trigger(\"selectedWells\", null, {selectedAddress: that.getSelectedAddress()});\n });\n\n if (color > 0) {\n color = ((color - 1) % (this.colorPairs.length - 1)) + 1;\n }\n var colorStops = this.colorPairs[color];\n\n plateIdDiv.css(\"background\", \"linear-gradient(to right, \" + colorStops[0] + \" , \" + colorStops[1] + \")\");\n\n row.append(plateIdDiv);\n\n for (var i = 0; i < this.globalSelectedAttributes.length; i++) {\n var attr = this.globalSelectedAttributes[i];\n var text = this.tileAttrText(modelTile, attr);\n var dataDiv = this._createElement(\"<td></td>\").text(text);\n row.append(dataDiv);\n }\n this.bottomTable.append(row);\n this.adjustFieldWidth(row);\n },\n\n bottomForFirstTime: function() {\n this.addBottomTableHeadings();\n // This is executed for the very first time.. !\n var row = this._createElement(\"<tr></tr>\");\n\n var colorStops = this.colorPairs[0];\n var plateIdDiv = this._createElement(\"<td></td>\");\n plateIdDiv.css(\"background\", \"-webkit-linear-gradient(left, \" + colorStops[0] + \" , \" + colorStops[1] + \")\");\n row.append(plateIdDiv);\n this.bottomTable.append(row);\n this.createExportButton();\n },\n\n adjustFieldWidth: function(row) {\n\n var length = this.rowCounter;\n if ((length) * 150 > 1024) {\n row.css(\"width\", (length) * 152 + \"px\");\n }\n },\n\n downloadCSV: function(csv, filename) {\n var csvFile;\n var downloadLink;\n\n // CSV file\n csvFile = new Blob([csv], {\n type: \"text/csv\"\n });\n\n // Download link\n downloadLink = document.createElement(\"a\");\n\n // File name\n downloadLink.download = filename;\n\n // Create a link to the file\n downloadLink.href = window.URL.createObjectURL(csvFile);\n\n // Hide download link\n downloadLink.style.display = \"none\";\n\n // Add the link to DOM\n document.body.appendChild(downloadLink);\n\n // Click download link\n downloadLink.click();\n },\n\n exportData: function(format) {\n var data = [];\n var rows = document.querySelectorAll(\"table tr\");\n\n var colorLocMap = {};\n var colorLocIdxMap = this.engine.stackUpWithColor;\n var dim = this.getDimensions();\n var that = this;\n for (var colorIdx in colorLocIdxMap) {\n colorLocMap[colorIdx] = colorLocIdxMap[colorIdx].map(function (locIdx) {\n return that.indexToAddress(locIdx, dim);\n })\n }\n\n for (var i = 0; i < rows.length; i++) {\n var row = [],\n cols = rows[i].querySelectorAll(\"td, th\");\n\n for (var j = 0; j < cols.length; j++) {\n var v = \"\";\n if (cols[j].innerText) {\n if (format === \"csv\") {\n v = '\"' + cols[j].innerText.replace(/\"/g, '\"\"') + '\"';\n } else {\n v = cols[j].innerText;\n }\n }\n row.push(v);\n\n // add location column\n if (i === 0 && j === 0) {\n if (format === \"csv\") {\n row.push('\"Location\"');\n } else if (format === 'clipboard') {\n row.push(\"Location\");\n }\n\n }\n if (i !== 0 && j === 0) {\n var loc = '';\n if (colorLocMap[parseInt(cols[j].innerText)]) {\n if (format === \"csv\") {\n loc = '\"' + colorLocMap[parseInt(cols[j].innerText)].join(\",\") + '\"';\n } else if (format === 'clipboard') {\n loc = colorLocMap[parseInt(cols[j].innerText)].join(\",\");\n }\n }\n row.push(loc);\n }\n }\n\n if (format === \"csv\") {\n data.push(row.join(\",\"));\n } else if (format === 'clipboard') {\n data.push(row.join(\"\\t\"));\n //data.push(row); // for text type\n }\n\n }\n if (format === \"csv\") {\n // Download CSV file\n this.downloadCSV(data.join(\"\\n\"), 'table.csv');\n } else if (format === 'clipboard') {\n //return formatTableToString(data); // for text type\n return data.join(\"\\n\");\n }\n },\n\n createExportButton: function() {\n var that = this;\n var overlayContainer = $(\"<div>\").addClass(\"plate-setup-bottom-control-container\");\n\n var descriptionDiv = $(\"<div>\").addClass(\"plate-setup-overlay-text-container\");\n descriptionDiv.text(\"Color groups\");\n overlayContainer.append(descriptionDiv);\n\n var buttonContainer = $(\"<div>\").addClass(\"plate-setup-overlay-bottom-button-container\");\n\n // create export csv option\n var exportButton = $(\"<button/>\").addClass(\"plate-setup-button\");\n exportButton.text(\"Export CSV\");\n buttonContainer.append(exportButton);\n\n exportButton.click(function() {\n that.exportData('csv');\n exportButton.text(\"Exported\");\n exportButton[0].classList.remove(\"plate-setup-button\");\n exportButton.addClass(\"plate-setup-clicked-button\");\n setTimeout(resetExportText, 3000);\n });\n\n function resetExportText() {\n exportButton.text(\"Export CSV\");\n exportButton[0].classList.remove(\"plate-setup-clicked-button\");\n exportButton.addClass(\"plate-setup-button\");\n }\n\n // creat clipboard option, CLipboard is an external js file located in vendor/asset/javascripts\n var clipboardButton = $(\"<button/>\").addClass(\"plate-setup-button\");\n clipboardButton.text(\"Copy To Clipboard\");\n buttonContainer.append(clipboardButton);\n\n var clipboard = new ClipboardJS(clipboardButton.get(0), {\n text: function() {\n return that.exportData(\"clipboard\");\n }\n });\n\n clipboard.on('success', function(e) {\n clipboardButton.text(\"Copied as tab-delimited format\");\n clipboardButton[0].classList.remove(\"plate-setup-button\");\n clipboardButton.addClass(\"plate-setup-clicked-button\");\n setTimeout(resetClipboardText, 3000);\n });\n\n function resetClipboardText() {\n clipboardButton.text(\"Copy To Clipboard\");\n clipboardButton[0].classList.remove(\"plate-setup-clicked-button\");\n clipboardButton.addClass(\"plate-setup-button\");\n }\n\n clipboard.on('error', function(e) {\n clipboardButton.text(\"Failed to copy table to clipboard: browser may be incompatible\");\n setTimeout(resetClipboardText, 3000);\n });\n\n overlayContainer.append(buttonContainer);\n $(\".plate-setup-bottom-container\").prepend(overlayContainer);\n }\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.canvas = function() {\n //\n return {\n\n allSelectedObjects: null, // Contains all the selected objets, when click and drag.\n\n allPreviouslySelectedObjects: null,\n\n colorPointer: 0,\n\n goldenRatio: 0.618033988749895,\n\n _createCanvas: function() {\n this.normalCanvas = this._createElement(\"<canvas>\").attr(\"id\", \"DNAcanvas\");\n $(this.canvasContainer).append(this.normalCanvas);\n },\n\n _initiateFabricCanvas: function() {\n var w = this.canvasContainer.width(); \n var h = this.canvasContainer.height(); \n\n this._setCanvasArea(w, h);\n\n this.mainFabricCanvas = new fabric.Canvas('DNAcanvas', {\n backgroundColor: '#f5f5f5',\n selection: false,\n stateful: false,\n hoverCursor: \"pointer\",\n renderOnAddRemove: false,\n })\n .setWidth(w)\n .setHeight(h);\n },\n\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.checkBox = function() {\n // For those check boxes associated with every field in the tab\n return {\n\n globalSelectedAttributes: [],\n\n _addCheckBox: function(field) {\n var checkImage = $(\"<span>\").html(this._assets.dontImg).addClass(\"plate-setup-tab-check-box bg-light\")\n .data(\"clicked\", false);\n checkImage.data(\"linkedFieldId\", field.id);\n field.root.find(\".plate-setup-tab-field-left-side\").empty().append(checkImage);\n this._applyCheckboxHandler(checkImage); // Adding handler for change the image when clicked\n field.checkbox = checkImage;\n },\n\n _applyCheckboxHandler: function(checkBoxImage) {\n // We add checkbox handler here, thing is it s not checkbox , its an image and we change\n // source\n var that = this;\n checkBoxImage.click(function(evt, machineClick) {\n var checkBox = $(this);\n\n var changes = {};\n changes[checkBox.data(\"linkedFieldId\")] = !checkBox.data(\"clicked\");\n\n that.changeCheckboxes(changes);\n });\n },\n\n changeSubFieldsCheckboxes: function(field, changes) {\n var that = this;\n var subFieldToInclude = [];\n\n field.subFieldList.forEach(function(subField) {\n var checkImage = subField.checkbox;\n var fieldId = checkImage.data(\"linkedFieldId\");\n var clicked = checkImage.data(\"clicked\");\n if (fieldId in changes) {\n clicked = Boolean(changes[fieldId]);\n }\n checkImage.data(\"clicked\", clicked);\n if (clicked) {\n checkImage.html(that._assets.doImg);\n subFieldToInclude.push(subField.id);\n } else {\n checkImage.html(that._assets.dontImg);\n }\n });\n return subFieldToInclude;\n },\n\n changeCheckboxes: function(changes) {\n var gsa = [];\n var multiplexCheckedSubField = {};\n for (var i = 0; i < this.fieldList.length; i++) {\n var field = this.fieldList[i];\n if (field.checkbox) {\n if (field.subFieldList) {\n multiplexCheckedSubField[field.id] = this.changeSubFieldsCheckboxes(field, changes);\n }\n\n var checkImage = field.checkbox;\n var fieldId = checkImage.data(\"linkedFieldId\");\n var clicked = checkImage.data(\"clicked\");\n if (fieldId in changes) {\n clicked = Boolean(changes[fieldId]);\n }\n checkImage.data(\"clicked\", clicked);\n if (clicked) {\n gsa.push(fieldId);\n checkImage.html(this._assets.doImg);\n } else {\n checkImage.html(this._assets.dontImg);\n }\n }\n }\n this.globalSelectedMultiplexSubfield = multiplexCheckedSubField;\n this.globalSelectedAttributes = gsa;\n this._clearPresetSelection();\n this._colorMixer();\n },\n\n setSubFieldCheckboxes: function(field, fieldIds) {\n var that = this;\n var subFieldToInclude = [];\n field.subFieldList.forEach(function(subField) {\n var checkImage = subField.checkbox;\n var fieldId = checkImage.data(\"linkedFieldId\");\n var clicked = fieldIds.indexOf(fieldId) >= 0;\n checkImage.data(\"clicked\", clicked);\n if (clicked) {\n checkImage.html(that._assets.doImg);\n subFieldToInclude.push(subField.id);\n } else {\n checkImage.html(that._assets.dontImg);\n }\n });\n return subFieldToInclude;\n },\n\n setCheckboxes: function(fieldIds) {\n fieldIds = fieldIds || [];\n var gsa = [];\n var multiplexCheckedSubField = {};\n\n for (var i = 0; i < this.fieldList.length; i++) {\n var field = this.fieldList[i];\n if (field.checkbox) {\n // special handling for multiplex field\n if (field.subFieldList) {\n multiplexCheckedSubField[field.id] = this.setSubFieldCheckboxes(field, fieldIds);\n }\n\n var checkImage = field.checkbox;\n var fieldId = checkImage.data(\"linkedFieldId\");\n var clicked = fieldIds.indexOf(fieldId) >= 0;\n checkImage.data(\"clicked\", clicked);\n if (clicked) {\n gsa.push(fieldId);\n checkImage.html(this._assets.doImg);\n } else {\n\n checkImage.html(this._assets.dontImg);\n }\n }\n }\n this.globalSelectedMultiplexSubfield = multiplexCheckedSubField;\n this.globalSelectedAttributes = gsa;\n this._clearPresetSelection();\n this._colorMixer();\n }\n\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.colorManager = function() {\n\n return {\n // See these are color pairs for the gradient.\n colorPairs: [\n [\"#e6e6e6\", \"#808080\"],\n [\"#66e8ff\", \"#0082c8\"],\n [\"#ff7fb1\", \"#e6194b\"],\n [\"#a2ffb1\", \"#3cb44b\"],\n [\"#f784ff\", \"#911eb4\"],\n [\"#ffe897\", \"#f58231\"],\n [\"#6666ff\", \"#0000FF\"],\n [\"#ffff7f\", \"#ffe119\"],\n [\"#acffff\", \"#46f0f0\"],\n [\"#ff98ff\", \"#f032e6\"],\n [\"#ffffa2\", \"#d2f53c\"],\n [\"#ffffff\", \"#fabebe\"],\n [\"#66e6e6\", \"#008080\"],\n [\"#ffffff\", \"#e6beff\"],\n [\"#ffd48e\", \"#aa6e28\"],\n [\"#e66666\", \"#800000\"],\n [\"#ffffff\", \"#aaffc3\"],\n [\"#e6e666\", \"#808000\"],\n [\"#ffffff\", \"#ffd8b1\"],\n [\"#66a9ef\", \"#004389\"],\n [\"#ff6672\", \"#a7000c\"],\n [\"#66db72\", \"#00750c\"],\n [\"#b866db\", \"#520075\"],\n [\"#ffa966\", \"#b64300\"],\n [\"#ffff66\", \"#c0a200\"],\n [\"#6dffff\", \"#07b1b1\"],\n [\"#ff66ff\", \"#b100a7\"],\n [\"#f9ff66\", \"#93b600\"],\n [\"#ffe5e5\", \"#bb7f7f\"],\n [\"#66a7a7\", \"#004141\"],\n [\"#ffe5ff\", \"#a77fc0\"],\n [\"#d19566\", \"#6b2f00\"],\n [\"#ffffef\", \"#c0bb89\"],\n [\"#d1ffea\", \"#6bc084\"],\n [\"#a7a766\", \"#414100\"],\n [\"#ffffd8\", \"#c09972\"],\n [\"#a5ffff\", \"#3fc1ff\"],\n [\"#ffbef0\", \"#ff588a\"],\n [\"#e1fff0\", \"#7bf38a\"],\n [\"#ffc3ff\", \"#d05df3\"],\n [\"#ffffd6\", \"#ffc170\"],\n [\"#a5a5ff\", \"#3f3fff\"],\n [\"#ffffbe\", \"#ffff58\"],\n [\"#ebffff\", \"#85ffff\"],\n [\"#ffd7ff\", \"#ff71ff\"],\n [\"#a5ffff\", \"#3fbfbf\"],\n [\"#ffffcd\", \"#e9ad67\"],\n [\"#ffa5a5\", \"#bf3f3f\"],\n [\"#ffffa5\", \"#bfbf3f\"]\n ]\n }\n }\n\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.createCanvasElements = function() {\n // this class manages creating all the elements within canvas\n return {\n\n scaleFactor: 1, \n\n baseSizes: {\n spacing: 48, \n tile_radius: 22, \n center_radius_complete: 10, \n center_radius_incomplete: 14, \n label_size: 14, \n label_spacing: 24, \n text_size: 13,\n stroke: 0.5, \n gap: 2\n }, \n\n _setCanvasArea: function(w, h) {\n this.scaleFactor = Math.min(\n h / (this.dimensions.rows * this.baseSizes.spacing + this.baseSizes.label_spacing), \n w / (this.dimensions.cols * this.baseSizes.spacing + this.baseSizes.label_spacing));\n\n var sizes = {}\n for (var prop in this.baseSizes) {\n sizes[prop] = this.baseSizes[prop] * this.scaleFactor; \n }\n this.sizes = sizes; \n }, \n\n _canvas: function() {\n // Those 1,2,3 s and A,B,C s\n this._fixRowAndColumn();\n\n // All those circles in the canvas.\n this._putCircles();\n },\n\n _fixRowAndColumn: function() {\n var cols = this.dimensions.cols;\n var rows = this.dimensions.rows;\n\n var spacing = this.sizes.spacing;\n var d1 = this.sizes.label_spacing / 2;\n var d2 = this.sizes.label_spacing + this.sizes.spacing / 2; \n var fontSize = this.sizes.label_size; \n\n // For column\n var top = d1; \n var left = d2; \n for (var i = 1; i <= cols; i++) {\n var tempFabricText = new fabric.IText(i.toString(), {\n fill: 'black',\n originX: 'center',\n originY: 'center',\n fontSize: fontSize,\n top: top,\n left: left,\n fontFamily: '\"Roboto\", Arial, sans-serif',\n selectable: false,\n fontWeight: \"400\"\n });\n left += spacing; \n\n this.mainFabricCanvas.add(tempFabricText);\n }\n\n // for row\n top = d2; \n left = d1; \n for (var i = 1; i <= rows; i++) {\n var tempFabricText = new fabric.IText(this.rowIndex[i-1], {\n fill: 'black',\n originX: 'center',\n originY: 'center',\n fontSize: fontSize,\n top: top,\n left: left,\n fontFamily: '\"Roboto\", Arial, sans-serif',\n selectable: false,\n fontWeight: \"400\"\n });\n top += spacing; \n\n this.mainFabricCanvas.add(tempFabricText);\n }\n },\n\n _putCircles: function() {\n var cols = this.dimensions.cols;\n var rows = this.dimensions.rows;\n\n var tileCounter = 0;\n for (var row = 0; row < rows; row++) {\n for (var col = 0; col < cols; col++) {\n var index = this.allTiles.length; \n var tile = this._createTile(row, col); \n tile.index = tileCounter++; \n this.allTiles.push(tile);\n this.mainFabricCanvas.add(tile.background);\n this.mainFabricCanvas.add(tile.highlight);\n this.mainFabricCanvas.add(tile.circle);\n this.mainFabricCanvas.add(tile.circleCenter);\n this.mainFabricCanvas.add(tile.circleText);\n }\n }\n\n this._addLargeRectangleOverlay();\n this._fabricEvents();\n },\n\n _createTile: function (row, col) {\n var tile = {}; \n\n tile.visible = false; \n tile.colorIndex = null; \n tile.row = row; \n tile.col = col; \n tile.address = this.rowIndex[row] + (col + 1); \n\n var top = (row + 1) * this.sizes.spacing;\n var left = (col + 1) * this.sizes.spacing; \n\n tile.background = new fabric.Circle({\n top: top,\n left: left,\n radius: this.sizes.tile_radius,\n originX: 'center',\n originY: 'center',\n hasControls: false,\n hasBorders: false,\n lockMovementX: true,\n lockMovementY: true,\n evented: false,\n });\n\n tile.background.setGradient(\"fill\", {\n type: \"radial\",\n x1: this.sizes.tile_radius, \n x2: this.sizes.tile_radius, \n y1: this.sizes.tile_radius + this.sizes.gap,\n y2: this.sizes.tile_radius + this.sizes.gap,\n r1: this.sizes.tile_radius - this.sizes.gap,\n r2: this.sizes.tile_radius,\n colorStops: {\n 0: 'rgba(0,0,0,0.1)',\n 1: 'rgba(0,0,0,0.2)'\n }\n });\n\n tile.highlight = new fabric.Rect({\n originX: 'center',\n originY: 'center',\n top: top,\n left: left,\n width: this.sizes.spacing,\n height: this.sizes.spacing,\n fill: \"rgba(0,0,0,0.4)\",\n evented: false,\n visible: false\n });\n\n tile.circle = new fabric.Circle({\n originX: 'center',\n originY: 'center',\n top: top,\n left: left,\n radius: this.sizes.tile_radius,\n stroke: 'gray',\n strokeWidth: this.sizes.stroke,\n evented: false, \n visible: false\n });\n\n tile.circleCenter = new fabric.Circle({\n originX: 'center',\n originY: 'center',\n top: top,\n left: left,\n radius: this.sizes.center_radius_incomplete,\n fill: \"white\",\n stroke: 'gray',\n strokeWidth: this.sizes.stroke,\n evented: false,\n visible: false\n });\n\n tile.circleText = new fabric.IText(\"\", {\n originX: 'center',\n originY: 'center',\n top: top,\n left: left,\n fill: 'black',\n fontFamily: '\"Roboto\", Arial, sans-serif',\n fontSize: this.sizes.text_size,\n lockScalingX: true,\n lockScalingY: true,\n evented: false,\n visible: false\n });\n\n return tile; \n }, \n\n setTileComplete: function (tile, complete) {\n if (complete) {\n tile.circleCenter.radius = this.sizes.center_radius_complete;\n tile.circleText.fill = \"black\";\n tile.circleText.fontWeight = 'normal';\n } else {\n tile.circleCenter.radius = this.sizes.center_radius_incomplete;\n tile.circleText.fill = \"red\";\n tile.circleText.fontWeight = 'bold';\n }\n }, \n\n setTileVisible: function (tile, visible) {\n tile.visible = visible;\n tile.circle.visible = tile.visible;\n tile.circleCenter.visible = tile.visible;\n tile.circleText.visible = tile.visible;\n },\n\n setTileColor: function(tile, color, stackPointer) {\n this.setTileVisible(tile, true);\n tile.colorIndex = parseInt(color); \n tile.circleText.text = String(tile.colorIndex);\n\n if (color > 0) {\n color = ((color - 1) % (this.colorPairs.length -1)) + 1;\n }\n var colorStops = this.colorPairs[color];\n\n tile.circle.setGradient(\"fill\", {\n y2: 2 * this.sizes.tile_radius,\n colorStops: colorStops\n });\n },\n\n _addLargeRectangleOverlay: function() {\n\n this.overLay = new fabric.Rect({\n width: 632,\n height: 482,\n left: 0,\n top: 0,\n opacity: 0.0,\n originX: 'left',\n originY: 'top',\n lockMovementY: true,\n lockMovementX: true,\n selectable: false\n });\n\n this.mainFabricCanvas.add(this.overLay);\n }\n };\n }\n})(jQuery, fabric);\n","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.createField = function() {\n // It create those fields in the tab , there is 4 types of them.\n return {\n\n _createField: function(field) {\n switch (field.data.type) {\n case \"text\":\n this._createTextField(field);\n break;\n\n case \"numeric\":\n this._createNumericField(field);\n break;\n\n case \"select\":\n this._createSelectField(field);\n break;\n\n case \"multiselect\":\n this._createMultiSelectField(field);\n break;\n\n case \"boolean\":\n this._createBooleanField(field);\n break;\n\n case \"multiplex\":\n this._createMultiplexField(field);\n break;\n }\n },\n\n _createTextField: function(field) {\n var id = field.id;\n var that = this;\n var input = this._createElement(\"<input>\").attr(\"id\", id)\n .addClass(\"plate-setup-tab-input\");\n\n field.root.find(\".plate-setup-tab-field-container\").append(input);\n that.defaultWell[id] = null;\n\n field.parseValue = function(v) {\n if (v) {\n v = String(v);\n } else {\n v = null;\n }\n return v;\n };\n\n field.getValue = function() {\n var v = input.val().trim();\n if (v == \"\") {\n v = null;\n }\n return v;\n };\n\n field.setValue = function(v) {\n input.val(v);\n };\n\n field.getText = function(v) {\n if (v == null) {\n return \"\";\n }\n return v;\n };\n\n field.disabled = function(bool) {\n field.input.prop(\"disabled\", bool);\n };\n\n field.parseText = field.parseValue;\n\n input.on(\"input\", function(e, generated) {\n field.onChange();\n });\n\n field.input = input;\n },\n\n _createOpts: function(config) {\n var opts = {\n allowClear: true,\n placeholder: \"select\",\n minimumResultsForSearch: 10\n };\n\n if (config.options) {\n opts.data = config.options;\n } else if (config.query) {\n var query = config.query;\n if (config.delay) {\n query = this._debounce(config.delay, query);\n }\n opts.query = query;\n } else {\n throw \"Must specify data or query\";\n }\n return opts;\n },\n\n _createSelectField: function(field) {\n var id = field.id;\n var that = this;\n var input = this._createElement(\"<input/>\").attr(\"id\", id)\n .addClass(\"plate-setup-tab-select-field\");\n\n field.root.find(\".plate-setup-tab-field-container\").append(input);\n that.defaultWell[id] = null;\n\n var opts = that._createOpts(field.data);\n var optMap = {};\n opts.data.forEach(function(opt) {\n optMap[opt.id] = opt;\n });\n\n input.select2(opts);\n\n field.parseValue = function(value) {\n var v = value;\n\n if (v == \"\") {\n v = null;\n }\n if (v == null) {\n return null;\n }\n if (v in optMap) {\n return optMap[v].id;\n } else {\n throw \"Invalid value \" + value + \" for select field \" + id;\n }\n };\n\n field.disabled = function(bool) {\n field.input.prop(\"disabled\", bool);\n };\n\n field.getValue = function() {\n var v = input.select2('data');\n return v ? v.id : null;\n };\n\n field.setValue = function(v) {\n if (v) {\n v = optMap[v];\n }\n input.select2('data', v);\n };\n\n field.setOpts = function(v) {\n input.select2('data', {});\n opts.data = v || [];\n input.select2(opts);\n };\n\n field.getText = function(v) {\n if (v == null) {\n return \"\";\n }\n return optMap[v].text;\n };\n\n field.parseText = function(value) {\n var v = value;\n\n if (v == \"\") {\n v = null;\n }\n if (v == null) {\n return null;\n }\n if (v in optMap) {\n return optMap[v].text;\n } else {\n throw \"Invalid text value \" + value + \" for select field \" + id;\n }\n };\n\n input.on(\"change\", function(e, generated) {\n field.onChange();\n });\n\n field.input = input;\n },\n\n _createMultiSelectField: function(field) {\n var id = field.id;\n var that = this;\n var input = this._createElement(\"<input/>\").attr(\"id\", id)\n .addClass(\"plate-setup-tab-multiselect-field\");\n input.attr(\"multiple\", \"multiple\");\n\n field.root.find(\".plate-setup-tab-field-container\").append(input);\n that.defaultWell[id] = null;\n\n var separator = \",\";\n var opts = that._createOpts(field.data);\n opts.multiple = true;\n var optMap = {};\n opts.data.forEach(function(opt) {\n optMap[opt.id] = opt;\n });\n input.select2(opts);\n\n field.disabled = function(bool) {\n field.input.prop(\"disabled\", bool);\n };\n\n field.parseValue = function(value) {\n var v = value;\n if (v && v.length) {\n v = v.map(function(opt) {\n if (opt in optMap) {\n return optMap[opt].id;\n } else {\n throw \"Invalid value \" + opt + \" for multiselect field \" + id;\n }\n });\n } else {\n v = null;\n }\n return v;\n };\n\n field.setOpts = function(v) {\n var allOpts = field.data.options;\n var selectedVal = [];\n for (var id in allOpts) {\n var curOpts = allOpts[id];\n if (v.indexOf(curOpts[\"id\"]) >= 0) {\n selectedVal.push(curOpts);\n }\n }\n\n opts.data = selectedVal;\n input.select2(opts);\n };\n\n field.getValue = function() {\n var v = input.select2('data');\n if (v.length) {\n return v.map(function(i) {\n return i.id;\n });\n }\n return null;\n };\n\n field.setValue = function(v) {\n v = v || [];\n v = v.map(function(i) {\n return optMap[i];\n });\n input.select2('data', v);\n };\n\n field.getText = function(v) {\n if (v == null) {\n return \"\";\n }\n if (v.length > 0) {\n return v.map(function(v) {\n return optMap[v].text\n }).join(\"; \");\n }\n return \"\";\n };\n\n field.multiOnChange = function (added, removed) {\n if (added) {\n added = added.id.toString();\n }\n if (removed) {\n removed = removed.id.toString();\n }\n var data = {\n };\n data[field.id] = {\n multi: true,\n added: added,\n removed: removed\n };\n\n that._addAllData(data);\n };\n\n field.parseText = function(value){\n var v = value;\n if (v && v.length) {\n v = v.map(function(opt) {\n if (opt in optMap) {\n return optMap[opt].text;\n } else {\n throw \"Invalid text value \" + opt + \" for multiselect field \" + id;\n }\n });\n } else {\n v = null;\n }\n return v;\n };\n\n input.on(\"change\", function(e, generated) {\n var added = e.added;\n var removed = e.removed;\n //field.onChange();\n field.multiOnChange(added, removed);\n });\n\n field.input = input;\n\n that._createDeleteButton(field);\n },\n\n _createNumericField: function(field) {\n var id = field.id;\n var data = field.data;\n var that = this;\n var input = this._createElement(\"<input>\").addClass(\"plate-setup-tab-input\")\n .attr(\"placeholder\", data.placeholder || \"\").attr(\"id\", id);\n\n field.root.find(\".plate-setup-tab-field-container\").append(input);\n that.defaultWell[id] = null;\n\n // Adding unit\n var units = data.units || [];\n var defaultUnit = data.defaultUnit || null;\n var unitInput = null;\n if (defaultUnit) {\n if (units.length) {\n if (units.indexOf(defaultUnit) < 0) {\n defaultUnit = units[0];\n }\n } else {\n units = [defaultUnit];\n }\n } else {\n if (units.length) {\n defaultUnit = units[0];\n }\n }\n\n if (units.length) {\n field.units = units;\n field.hasUnits = true;\n field.defaultUnit = defaultUnit;\n if (units.length == 1) {\n var unitText = $(\"<div></div>\").addClass(\"plate-setup-tab-unit\");\n unitText.text(defaultUnit);\n field.root.find(\".plate-setup-tab-field-container\").append(unitText);\n } else {\n unitInput = this._createElement(\"<input/>\").attr(\"id\", id)\n .addClass(\"plate-setup-tab-label-select-field\");\n\n field.root.find(\".plate-setup-tab-field-container\").append(unitInput);\n\n var selected = null;\n var unitData = units.map(function(unit) {\n var o = {\n id: unit,\n text: unit\n };\n if (unit == defaultUnit) {\n selected = o;\n }\n return o;\n });\n\n var opts = {\n data: unitData,\n allowClear: false,\n minimumResultsForSearch: 10\n };\n\n unitInput.select2(opts);\n unitInput.select2(\"data\", selected);\n }\n }\n\n field.disabled = function(bool) {\n field.input.prop(\"disabled\", bool);\n if (unitInput) {\n unitInput.prop(\"disabled\", bool);\n }\n };\n\n field.setUnitOpts = function(opts) {\n field.units = opts || null;\n field.defaultUnit = null;\n\n var newUnits = [];\n var selected = null;\n if (field.units && field.units.length) {\n field.defaultUnit = field.units[0];\n newUnits = field.units.map(function(curUnit) {\n var cleanUnit = {\n id: curUnit,\n text: curUnit\n };\n if (curUnit == field.defaultUnit) {\n selected = cleanUnit;\n }\n return cleanUnit;\n });\n }\n\n var newOpts = {\n data: newUnits,\n allowClear: false,\n minimumResultsForSearch: 10\n };\n unitInput.select2(newOpts);\n unitInput.select2(\"data\", selected);\n };\n\n field.parseValue = function(value) {\n var v;\n if ($.isPlainObject(value)) {\n if (field.hasUnits) {\n v = field.parseRegularValue(value.value);\n if (v === null) {\n return null;\n }\n return {\n value: v,\n unit: field.parseUnit(value.unit)\n };\n } else {\n throw \"Value must be plain numeric for numeric field \" + id;\n }\n } else {\n if (field.hasUnits) {\n v = field.parseRegularValue(value);\n if (v === null) {\n return null;\n }\n return {\n value: v,\n unit: field.defaultUnit\n };\n } else {\n return field.parseRegularValue(value);\n }\n }\n };\n\n field.getValue = function() {\n var v = field.getRegularValue();\n\n if ((v === null) || isNaN(v)) {\n return null;\n } else if (field.hasUnits) {\n var returnVal = {\n value: v,\n unit: field.getUnit()\n };\n\n if (field.data.hasMultiplexUnit) {\n // include unitTypeId and UnitId to returnVal\n for (var unitTypeKey in field.data.unitMap) {\n var unitTypeUnits = field.data.unitMap[unitTypeKey];\n unitTypeUnits.forEach(function(unit) {\n if (unit.text === returnVal.unit) {\n returnVal['unitTypeId'] = unitTypeKey;\n returnVal['unitId'] = unit.id;\n }\n })\n }\n }\n return returnVal;\n } else {\n return v;\n }\n };\n\n field.setValue = function(value) {\n if (field.hasUnits) {\n if ($.isPlainObject(value)) {\n field.setUnit(value.unit || field.defaultUnit);\n field.setRegularValue(value.value);\n\n } else {\n field.setRegularValue(value);\n field.setUnit(field.defaultUnit)\n }\n } else {\n field.setRegularValue(value);\n }\n };\n\n field.parseRegularValue = function(value) {\n if (value == null) {\n return null;\n }\n var v = String(value).trim();\n if (v === \"\") {\n return null;\n }\n v = Number(value);\n if (isNaN(v)) {\n throw \"Invalid value \" + value + \" for numeric field \" + id;\n }\n return v;\n };\n\n field.getRegularValue = function() {\n var v = input.val().trim();\n if (v == \"\") {\n v = null;\n } else {\n v = Number(v);\n }\n return v;\n };\n\n field.setRegularValue = function(value) {\n input.val(value);\n };\n\n field.parseUnit = function(unit) {\n if (unit == null || unit === \"\") {\n return field.defaultUnit;\n }\n for (var i = 0; i < units.length; i++) {\n if (unit.toLowerCase() == units[i].toLowerCase()) {\n return units[i];\n }\n }\n throw \"Invalid unit \" + unit + \" for field \" + id;\n };\n\n field.getUnit = function() {\n if (unitInput) {\n return unitInput.val();\n } else {\n return field.defaultUnit;\n }\n };\n\n field.setUnit = function(unit) {\n if (unitInput) {\n unit = unit || field.defaultUnit;\n if (unit != null) {\n unit = {\n id: unit,\n text: unit\n };\n }\n unitInput.select2(\"data\", unit);\n }\n };\n\n // val now contains unit\n field.getText = function(val) {\n if (typeof(val) === 'object' && val) {\n var v = val.value;\n var u = val.unit;\n if (v == null) {\n return \"\";\n }\n v = v.toString();\n if (!u) {\n u = defaultUnit;\n }\n if (u) {\n v = v + \" \" + u;\n }\n return v;\n } else {\n return field.getRegularText(val);\n }\n };\n\n field.getRegularText = function(v) {\n if (v == null) {\n return \"\";\n }\n v = v.toString();\n return v;\n };\n\n field.parseText = function(v){\n var textVal = field.parseValue(v);\n if (textVal && typeof(textVal) === \"object\"){\n return textVal.value + textVal.unit;\n } else if (textVal) {\n return textVal\n } else {\n return null;\n }\n };\n\n input.on(\"input\", function() {\n var v = field.getRegularValue();\n if (isNaN(v)) {\n //flag field as invalid\n input.addClass(\"invalid\");\n } else {\n input.removeClass(\"invalid\");\n }\n field.onChange();\n });\n if (unitInput) {\n unitInput.on(\"change\", function() {\n field.onChange();\n });\n }\n\n field.input = input;\n field.unitInput = unitInput;\n },\n\n _createBooleanField: function(field) {\n var id = field.id;\n var that = this;\n var input = this._createElement(\"<input/>\").attr(\"id\", id)\n .addClass(\"plate-setup-tab-select-field\");\n that.defaultWell[id] = null;\n\n field.root.find(\".plate-setup-tab-field-container\").append(input);\n var tval = {\n id: \"true\",\n text: \"true\"\n };\n var fval = {\n id: \"false\",\n text: \"false\"\n };\n var opts = {\n data: [tval, fval],\n placeholder: \"select\",\n allowClear: true,\n minimumResultsForSearch: -1,\n initSelection: function(element, callback) {\n var v = element.val();\n callback({\n id: v,\n text: v\n });\n }\n };\n\n input.select2(opts);\n\n field.disabled = function(bool) {\n field.input.prop(\"disabled\", bool);\n };\n\n field.parseValue = function(value) {\n if (value == null) {\n return null;\n }\n var v = String(value).trim().toLowerCase();\n if (v == \"true\") {\n v = true;\n } else if (v == \"false\") {\n v = false;\n } else if (v == \"\") {\n v = null;\n } else {\n throw \"Invalid value \" + value + \" for boolean field \" + id;\n }\n return v;\n };\n\n field.getValue = function() {\n var v = input.val();\n switch (v) {\n case \"true\":\n return true;\n case \"false\":\n return false;\n default:\n return null;\n }\n };\n\n field.setValue = function(v) {\n if (v == true || v == \"true\") {\n v = tval;\n } else if (v == false || v == \"false\") {\n v = fval;\n } else {\n v = null;\n }\n input.select2('data', v);\n };\n\n field.getText = function(v) {\n if (v == null) {\n return \"\";\n }\n return v.toString();\n };\n\n field.parseText = field.parseValue;\n\n input.on(\"change\", function(e) {\n field.onChange();\n });\n\n field.input = input;\n },\n\n _createMultiplexField: function(field) {\n var that = this;\n // make correct multiplex data\n this._createMultiSelectField(field);\n // overwrite default well for multiplex field\n that.defaultWell[field.id] = [];\n\n // single select\n var nameContainer1 = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-name-singleSelect\").text(\"Select to edit\");\n var fieldContainer1 = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab-field-container-singleSelect\");\n field.root.find(\".plate-setup-tab-field-right-side\").append(nameContainer1, fieldContainer1);\n\n field.singleSelect = this._createElement(\"<input/>\").attr(\"id\", field.id + \"SingleSelect\")\n .addClass(\"plate-setup-tab-multiplex-single-select-field\");\n\n field.singleSelect.appendTo(fieldContainer1);\n\n field.singleSelectValue = function () {\n var v = field.singleSelect.select2(\"data\");\n if (v != null) {\n v = v.id;\n }\n return v;\n };\n\n var setSingleSelectOptions = function (v, selected_v) {\n var opts = {\n allowClear: false,\n placeholder: \"select\",\n minimumResultsForSearch: 10,\n data: v || []\n }\n if (!selected_v) {\n if (opts.data.length) {\n selected_v = opts.data[0];\n } else {\n selected_v = null;\n }\n }\n field.singleSelect.select2('data', []);\n field.singleSelect.select2(opts);\n field.singleSelect.select2('data', selected_v);\n field.singleSelect.prop(\"disabled\", opts.data.length == 0);\n };\n\n var singleSelectChange = function () {\n var v = field.singleSelectValue();\n\n field.updateSubFieldUnitOpts(v);\n\n var curData = field.detailData || [];\n var curSubField = null;\n curData.forEach(function(val) {\n if (val[field.id] === v) {\n curSubField = val;\n }\n });\n\n if (curSubField) {\n // setvalue for subfield\n field.subFieldList.forEach(function(subField) {\n subField.disabled(false);\n subField.setValue(curSubField[subField.id]);\n });\n } else {\n field.subFieldList.forEach(function(subField) {\n subField.disabled(true);\n subField.setValue(null);\n });\n }\n that.readOnlyHandler();\n };\n\n setSingleSelectOptions([]);\n\n field.singleSelect.on(\"change\", singleSelectChange);\n\n field._changeMultiFieldValue = function(added, removed) {\n var newSubFieldValue = {};\n for (var subFieldName in field.data.multiplexFields) {\n var subFieldId = field.data.multiplexFields[subFieldName].id;\n newSubFieldValue[subFieldId] = null;\n }\n\n var val;\n if (added) {\n if (added.value) {\n val = added.value;\n } else {\n newSubFieldValue[field.id] = added.id;\n val = newSubFieldValue;\n }\n added = {\n id: added.id,\n value: val\n };\n }\n\n if (removed) {\n if (removed.value){\n val = removed.value;\n } else {\n newSubFieldValue[field.id] = removed.id;\n val = newSubFieldValue;\n }\n removed = {\n id: removed.id,\n value: val\n };\n }\n\n var data = {};\n data[field.id] = {\n multi: true,\n added: added,\n removed: removed\n };\n that._addAllData(data);\n };\n\n var multiselectSetValue = field.setValue;\n\n // overwrite multiplex set value\n field.setValue = function(v) {\n // used to keep track of initially loaded multiplex data\n field.detailData = v;\n var multiselectValues = null;\n if (v && v.length) {\n multiselectValues = v.map(function(val) {\n return val[field.id]\n });\n }\n\n multiselectSetValue(multiselectValues);\n var newOptions = field.input.select2('data') || [];\n setSingleSelectOptions(newOptions);\n singleSelectChange();\n };\n\n field.disabled = function(bool) {\n field.input.prop(\"disabled\", bool);\n field.subFieldList.forEach(function(subField) {\n subField.disabled(bool);\n });\n if (bool) {\n nameContainer1.text(\"Select to inspect\");\n } else {\n nameContainer1.text(\"Select to edit\");\n }\n };\n\n field.parseValue = function(value) {\n var v = value;\n if (v && v.length) {\n v = v.map(function(opt) {\n var valMap = {};\n valMap[field.id] = opt[field.id];\n for (var subFieldId in opt) {\n field.subFieldList.forEach(function(subField) {\n if (subField.id === subFieldId) {\n valMap[subField.id] = subField.parseValue(opt[subFieldId]);\n }\n });\n }\n return valMap;\n });\n } else {\n v = null;\n }\n return v;\n };\n\n field.updateSubFieldUnitOpts = function(val) {\n var curOpts;\n field.data.options.forEach(function(opt) {\n if (opt.id === val) {\n curOpts = opt;\n }\n });\n field.subFieldList.forEach(function(subField) {\n if (subField.data.hasMultiplexUnit) {\n if (curOpts && curOpts.hasOwnProperty(\"unitOptions\")) {\n\t\t\t\t\t\t\t\tsubField.setUnitOpts(curOpts.unitOptions[subField.id]);\n } else {\n subField.setUnitOpts(null);\n }\n }\n })\n };\n\n field.multiOnChange = function(added, removed) {\n field._changeMultiFieldValue(added, removed);\n var v = field.getValue();\n var curData = field.detailData;\n var curIds = [];\n var curOpt = null;\n //reshape data for saveback\n if (curData) {\n curIds = curData.map(function(val) {\n return val[field.id]\n });\n }\n\n var newMultiplexVal = [];\n var selectList = [];\n if (v) {\n v.forEach(function(selectedVal) {\n if (curData) {\n curData.forEach(function(val) {\n if (val[field.id] === selectedVal) {\n newMultiplexVal.push(val)\n }\n });\n }\n // cases when adding new data\n if (curIds.indexOf(selectedVal) < 0) {\n var newVal = {};\n newVal[field.id] = selectedVal;\n\n field.updateSubFieldUnitOpts(selectedVal);\n field.subFieldList.forEach(function(subfield) {\n // special handling for subfield which has multiplexUnit\n if (subfield.hasUnits) {\n if (subfield.data.hasMultiplexUnit) {\n subfield.disabled(false);\n field.data.options.forEach(function(opt) {\n if (opt.id === selectedVal) {\n var val = {\n value: null,\n unit: subfield.units[0]\n };\n newVal[subfield.id] = subfield.parseValue(val);\n }\n });\n } else {\n if (subfield.data.units) {\n if (subfield.data.units.length > 1){\n subfield.disabled(false);\n }\n }\n var val = {\n value: null,\n unit: subfield.defaultUnit\n };\n newVal[subfield.id] = subfield.parseValue(val);\n }\n }\n else {\n newVal[subfield.id] = subfield.parseValue(null);\n }\n });\n newMultiplexVal.push(newVal);\n }\n });\n\n // make data for single select options\n v.forEach(function(selectId) {\n field.data.options.forEach(function(opt) {\n if (opt.id === selectId) {\n selectList.push(opt);\n }\n });\n });\n // set the newest selected to be the current obj\n curOpt = selectList[v.length - 1];\n }\n\n field.detailData = newMultiplexVal;\n setSingleSelectOptions(selectList, curOpt);\n singleSelectChange();\n };\n\n field.getText = function(v) {\n if (v === null) {\n return \"\";\n }\n // get subfields that is selected from the checkbox\n if (field.id in that.globalSelectedMultiplexSubfield) {\n var checkedSubfields = that.globalSelectedMultiplexSubfield[field.id];\n var returnVal = [];\n for (var valIdx in v) {\n var subV = v[valIdx];\n var subText = [];\n for (var optId in field.data.options) {\n var opt = field.data.options[optId];\n if (opt.id === subV[field.id]) {\n subText.push(opt.text);\n }\n }\n field.subFieldList.forEach(function(subField) {\n if (checkedSubfields.indexOf(subField.id) >= 0) {\n var x = subField.getText(subV[subField.id]);\n subText.push(subField.name + \": \" + x);\n }\n });\n returnVal.push(\"{\" + subText.join(\", \") + \"}\");\n }\n return returnVal.join(\";\");\n }\n };\n\n field.parseText = function(v) {\n if (v === null) {\n return \"\";\n } else {\n var returnVal = [];\n for (var valIdx in v) {\n var subV = v[valIdx];\n var subText = [];\n for (var optId in field.data.options) {\n var opt = field.data.options[optId];\n if (opt.id === subV[field.id]) {\n subText.push(opt.text);\n }\n }\n field.subFieldList.forEach(function(subField) {\n var x = subField.getText(subV[subField.id]);\n if (x) {\n subText.push(x);\n }\n });\n returnVal.push(subText);\n }\n return returnVal;\n }\n };\n\n field.checkMultiplexCompletion = function(valList) {\n var valCount = 0;\n var completionPct = 0;\n var include = false;\n function getSubfieldStatus (vals) {\n var req = 0;\n var fill = 0;\n for (var subFieldId in field.subFieldList) {\n var subField = field.subFieldList[subFieldId];\n var curVal = vals[subField.id];\n if (subField.required) {\n include = true;\n req++;\n if (typeof(curVal) === 'object' && curVal) {\n if (curVal.value) {\n fill++;\n }\n } else if (curVal) {\n fill++;\n }\n }\n }\n return fill/req;\n }\n\n // for cases has value in multiplex field\n if (valList) {\n if (valList.length > 0){\n for (var idx in valList) {\n valCount++;\n var vals = valList[idx];\n completionPct += getSubfieldStatus(vals);\n }\n } else if (field.required) {\n include = true;\n valCount = 1;\n }\n } else if (field.required) {\n include = true;\n valCount = 1;\n }\n\n return {\n include: include,\n completionPct: completionPct/valCount\n };\n };\n\n // valList contains all of the vals for selected val\n field.applyMultiplexSubFieldColor = function(valList){\n function updateSubFieldWarningMap (vals) {\n for (var subFieldId in field.subFieldList) {\n var subField = field.subFieldList[subFieldId];\n // loop through each well's multiplexval list\n if (vals === null){\n if (field.required && subField.required){\n subFieldWarningMap[subField.id].warningStatus.push(true);\n }\n } else if (typeof(vals) === \"object\") {\n if (vals.length === 0) {\n if (field.required && subField.required){\n subFieldWarningMap[subField.id].warningStatus.push(true);\n }\n } else {\n for (var multiplexIdx in vals) {\n var curVal = vals[multiplexIdx][subField.id];\n if (subField.required) {\n if (typeof(curVal) === 'object' && curVal) {\n if (!curVal.value) {\n subFieldWarningMap[subField.id].warningStatus.push(true);\n } else {\n subFieldWarningMap[subField.id].warningStatus.push(false);\n }\n } else if (!curVal) {\n subFieldWarningMap[subField.id].warningStatus.push(true);\n } else {\n subFieldWarningMap[subField.id].warningStatus.push(false);\n }\n }\n }\n }\n }\n }\n }\n\n var subFieldWarningMap = {};\n field.subFieldList.forEach(function(subField){\n if (subField.required) {\n subFieldWarningMap[subField.id] = {\n field: subField,\n warningStatus: []\n };\n }\n });\n\n valList.forEach(function(multiplexVals) {\n updateSubFieldWarningMap(multiplexVals);\n });\n // turn off main field when all subfield are filled\n\n var requiredSubField = [];\n var mainFieldStatus = [];\n for (var subFieldId in subFieldWarningMap){\n var subField = subFieldWarningMap[subFieldId].field;\n if (subFieldWarningMap[subFieldId].warningStatus.indexOf(true) >= 0) {\n var text = subField.name + \" is a required subfield for \" + field.name + \", please make sure all \" + field.name + \" have \" + subField.name;\n if (field.required){\n that.fieldWarningMsg(subField, text, true);\n mainFieldStatus.push(true);\n } else {\n that.fieldWarningMsg(subField, text, true);\n mainFieldStatus.push(true);\n }\n } else {\n that.fieldWarningMsg(subField, \"none\", false);\n mainFieldStatus.push(false);\n }\n }\n var mainFieldWarning = false;\n if (mainFieldStatus.indexOf(true) < 0) {\n mainFieldWarning = false;\n } else {\n mainFieldWarning = true;\n }\n var warningText;\n if (field.required) {\n warningText = field.name + \" is a required field, please also fix missing required subfield(s) below\";\n } else {\n warningText = field.name + \" is not a required field, please fix missing required subfield(s) below or remove selected \" + field.name;\n }\n that.fieldWarningMsg(field, warningText, mainFieldWarning);\n };\n\n field.parseMainFieldVal = function(val) {\n var optMap = field.data.options;\n for (var idx = 0; idx < optMap.length; idx++){\n var curOpt = optMap[idx];\n if (curOpt.id === val){\n return curOpt.text\n }\n }\n };\n },\n\n _deleteDialog: function (field) {\n var that = this;\n\n var valMap = field.allSelectedMultipleVal;\n var valToRemove;\n if (valMap) {\n valToRemove = Object.keys(valMap);\n } else {\n valToRemove = [];\n }\n\n\n var dialogDiv = $(\"<div/>\").addClass(\"delete-dialog modal\");\n $('body').append(dialogDiv);\n\n function killDialog() {\n dialogDiv.hide();\n dialogDiv.remove();\n }\n\n var dialogContent = $(\"<div/>\").addClass(\"modal-content\").appendTo(dialogDiv);\n var tableArea = $(\"<div/>\").appendTo(dialogContent);\n var buttonRow = $(\"<div/>\").addClass(\"dialog-buttons\").css(\"justify-content\", \"flex-end\").appendTo(dialogContent);\n\n if (valToRemove.length > 0){\n // apply CSS property for table\n $(\"<p/>\").text(field.name + \" in selected wells: choose items to delete and click the delete button below\").appendTo(tableArea);\n\n var table = that._deleteDialogTable(field, valMap);\n table.appendTo(tableArea);\n table.addClass(\"plate-popout-table\");\n table.find('td').addClass(\"plate-popout-td\");\n table.find('th').addClass(\"plate-popout-th\");\n table.find('tr').addClass(\"plate-popout-tr\");\n if (!that.readOnly) {\n var deleteCheckedButton = $(\"<button class='multiple-field-manage-delete-button'>Delete Checked Items</button>\");\n buttonRow.append(deleteCheckedButton);\n deleteCheckedButton.click(function() {\n table.find(\"input:checked\").each(function () {\n var val = this.value;\n field.multiOnChange(null, {id: val});\n });\n // refresh selected fields after updating the multiplex field value\n that.decideSelectedFields();\n killDialog();\n });\n }\n\n } else {\n $(\"<p/>\").text(\"No \" + field.name + \" in the selected wells\").appendTo(tableArea);\n }\n\n var cancelButton = $(\"<button>Cancel</button>\");\n buttonRow.append(cancelButton);\n cancelButton.click(killDialog);\n\n dialogDiv.show();\n\n window.onclick = function(event) {\n if (event.target == dialogDiv[0]) {\n killDialog();\n }\n }\n },\n\n _deleteDialogTable: function (field, valMap) {\n var that = this;\n var colName = [field.name, \"Counts\"]; //Added because it was missing... no idea what the original should have been\n if (!that.readOnly) {\n colName.push(\"Delete\");\n }\n var table = $('<table/>');\n var thead = $('<thead/>').appendTo(table);\n var tr = $('<tr/>').appendTo(thead);\n\n tr.append(colName.map(function (text) {\n return $('<th/>').text(text);\n }));\n\n var tbody = $(\"<tbody/>\").appendTo(table);\n\n field.data.options.forEach(function (opt) {\n if (opt.id in valMap) {\n var tr = $('<tr/>').appendTo(tbody);\n var checkbox = $(\"<input type='checkbox'>\").prop(\"value\", opt.id);\n $(\"<td/>\").text(opt.text).appendTo(tr);\n $(\"<td/>\").text(valMap[opt.id]).appendTo(tr);\n if (!that.readOnly) {\n $(\"<td/>\").append(checkbox).appendTo(tr);\n }\n }\n });\n\n return table;\n },\n\n _createDeleteButton: function (field) {\n var that = this;\n var deleteButton = $(\"<button/>\").addClass(\"plate-setup-remove-all-button\");\n deleteButton.id = field.id + \"Delete\";\n deleteButton.text(\"Manage \" + field.name + \"...\");\n var buttonContainer = that._createElement(\"<div></div>\").addClass(\"plate-setup-remove-all-button-container\");\n buttonContainer.append(deleteButton);\n\n field.deleteButton = deleteButton;\n field.root.find(\".plate-setup-tab-field-right-side\").append(buttonContainer);\n\n deleteButton.click(function () {\n that._deleteDialog(field);\n });\n }\n\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.engine = function(THIS) {\n // Methods which look after data changes and stack up accordingly\n // Remember THIS points to plateLayOutWidget and 'this' points to engine\n // Use THIS to refer parent this.\n return {\n engine: {\n\n derivative: {},\n stackUpWithColor: {},\n stackPointer: 2,\n\n wellEmpty: function (well) {\n for (var prop in well) {\n var curVal = well[prop];\n if (curVal !== null && curVal !== undefined) {\n if (Array.isArray(curVal)) {\n if (curVal.length > 0) {\n return false;\n }\n } else {\n return false;\n }\n }\n }\n return true;\n },\n\n searchAndStack: function() {\n // This method search and stack the change we made.\n this.stackUpWithColor = {};\n this.stackPointer = 1;\n var derivativeJson = {};\n for (var idx in this.derivative) {\n var data = this.derivative[idx];\n var wellData = {};\n for (var i = 0; i < THIS.globalSelectedAttributes.length; i++) {\n var attr = THIS.globalSelectedAttributes[i]; \n\n if (attr in THIS.globalSelectedMultiplexSubfield){\n var selectedSubFields = THIS.globalSelectedMultiplexSubfield[attr];\n var newMultiplexVal = [];\n for (var multiplexIdx in data[attr]){\n var curMultiplexVals = data[attr][multiplexIdx];\n var newVal = {};\n newVal[attr] = curMultiplexVals[attr];\n selectedSubFields.forEach(function (subFieldId) {\n newVal[subFieldId] = curMultiplexVals[subFieldId];\n });\n newMultiplexVal.push(newVal);\n }\n wellData[attr] = newMultiplexVal;\n } else {\n if (data[attr] != null) {\n wellData[attr] = data[attr];\n }\n }\n }\n if ($.isEmptyObject(wellData)) {\n derivativeJson[idx] = null; \n } else {\n derivativeJson[idx] = JSON.stringify(wellData);\n }\n }\n\n while (!$.isEmptyObject(derivativeJson)) {\n var keys = Object.keys(derivativeJson).map(function (k) {return parseFloat(k, 10);});\n keys.sort(function (a, b) {return a-b;}); \n\n var refDerivativeIndex = keys[0];\n var referenceDerivative = derivativeJson[refDerivativeIndex];\n var arr = [];\n\n if (!referenceDerivative) {\n // if no checked box has value, push it to first spot\n if (this.stackUpWithColor[0]) {\n this.stackUpWithColor[0].push(refDerivativeIndex);\n } else {\n this.stackUpWithColor[0] = [refDerivativeIndex];\n }\n\n delete derivativeJson[refDerivativeIndex];\n } else {\n // if checked boxes have values\n for (var i = 0; i < keys.length; i++) {\n var idx = keys[i]; \n if (referenceDerivative == derivativeJson[idx]) {\n arr.push(idx);\n this.stackUpWithColor[this.stackPointer] = arr;\n delete derivativeJson[idx];\n }\n }\n if (arr.length > 0)\n this.stackPointer++;\n }\n }\n },\n\n applyColors: function() {\n\n var wholeNoTiles = 0;\n var wholePercentage = 0;\n\n THIS.addBottomTableHeadings();\n\n for (var i = 0; i < THIS.allTiles.length; i++) {\n var tile = THIS.allTiles[i];\n THIS.setTileVisible(tile, false);\n }\n\n for (var color = 0; color < this.stackPointer; color++) {\n var arr = this.stackUpWithColor[color];\n if (arr) {\n THIS.addBottomTableRow(color, arr);\n\n for (var tileIndex in arr) {\n wholeNoTiles++;\n var index = this.stackUpWithColor[color][tileIndex]; \n var tile = THIS.allTiles[index];\n var well = this.derivative[index];\n THIS.setTileColor(tile, color, this.stackPointer); \n // Checks if all the required fields are filled\n var completion = this.checkCompletion(well, tile);\n THIS.setTileComplete(tile, completion == 1); \n wholePercentage = wholePercentage + completion;\n }\n }\n }\n\n wholePercentage = Math.floor(100 * wholePercentage / wholeNoTiles);\n\n if (isNaN(wholePercentage)) {\n THIS.overLayTextContainer.text(\"Completion Percentage: 0%\");\n } else {\n THIS.overLayTextContainer.text(\"Completion Percentage: \" + wholePercentage + \"%\");\n }\n },\n\n checkCompletion: function(wellData, tile) {\n var req = 0; \n var fill = 0;\n for (var i = 0; i < THIS.fieldList.length; i++) {\n var field = THIS.fieldList[i];\n if (field.checkMultiplexCompletion){\n // also apply color\n var multiplexStatus = field.checkMultiplexCompletion(wellData[field.id]);\n if (multiplexStatus.include) {\n fill += multiplexStatus.completionPct;\n req++;\n }\n } else {\n if (field.required) {\n req++;\n if (wellData[field.id] !== null) {\n fill++;\n }\n }\n }\n }\n if (req === fill) {\n return 1; \n }\n return fill / req;\n },\n }\n }\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.fabricEvents = function() {\n // This object contains Menu items and how it works;\n return {\n colorToIndex: {},\n startCoords: {\n x: 0,\n y: 0\n },\n focalWell: {\n row: 0,\n col: 0\n },\n selectedAreas: [],\n\n _clickCoords: function(evt) {\n //Get XY Coords for a given event. \n var rect = evt.e.target.getBoundingClientRect();\n return {\n x: evt.e.clientX - rect.left,\n y: evt.e.clientY - rect.top\n };\n },\n\n _fabricEvents: function() {\n // Set up event handling. \n var that = this;\n\n $(that.target).on(\"getPlates\", function(evt, data) {\n // This method should be compatable to redo/undo.\n that.getPlates(JSON.parse(data));\n });\n\n that.mainFabricCanvas.on(\"mouse:down\", function(evt) {\n // Start selecting new area\n that.selecting = true;\n var coords = that._clickCoords(evt);\n\n var areas = that.selectedAreas.slice();\n var focalWell = that.focalWell;\n var startCoords = that._wellToCoords(focalWell, true);\n var rect = that._coordsToRect(startCoords, coords);\n\n if (evt.e.ctrlKey) {\n //adding new area\n startCoords = coords;\n rect = that._coordsToRect(startCoords, coords);\n focalWell = that._coordsToWell(startCoords);\n if (evt.e.shiftKey) {\n //replacing existing areas\n areas = [that._rectToArea(rect)];\n } else {\n areas.push(that._rectToArea(rect));\n }\n } else {\n if (evt.e.shiftKey) {\n //Altering last area\n areas[areas.length - 1] = that._rectToArea(rect);\n } else {\n //Creating new area\n startCoords = coords;\n rect = that._coordsToRect(startCoords, coords);\n focalWell = that._coordsToWell(startCoords);\n areas = [that._rectToArea(rect)];\n }\n }\n\n that.startCoords = startCoords;\n that.setSelection(areas, focalWell);\n that.mainFabricCanvas.renderAll();\n });\n\n that.mainFabricCanvas.on(\"mouse:move\", function(evt) {\n if (that.selecting) {\n // continue selecting new area\n var areas = that.selectedAreas.slice();\n var endCoords = that._clickCoords(evt);\n var rect = that._coordsToRect(that.startCoords, endCoords);\n var area = that._rectToArea(rect);\n if (area) {\n areas[areas.length - 1] = area;\n }\n\n that.setSelection(areas, that.focalWell);\n that.mainFabricCanvas.renderAll();\n }\n\n });\n\n that.mainFabricCanvas.on(\"mouse:up\", function(evt) {\n // finish selecting new area\n that.selecting = false;\n var areas = that.selectedAreas.slice();\n var endCoords = that._clickCoords(evt);\n var rect = that._coordsToRect(that.startCoords, endCoords);\n var area = that._rectToArea(rect);\n if (area) {\n areas[areas.length - 1] = area;\n }\n\n that.setSelection(areas, that.focalWell);\n that.decideSelectedFields();\n that.mainFabricCanvas.renderAll();\n that._trigger(\"selectedWells\", null, {selectedAddress: that.getSelectedAddress()});\n });\n },\n\n setSelection: function(areas, focalWell) {\n this.selectedAreas = areas;\n this.focalWell = focalWell;\n this.allSelectedObjects = this._areasToTiles(areas);\n this._setSelectedTiles();\n this._setFocalWellRect(this.focalWell);\n document.activeElement.blur();\n },\n\n _setFocalWellRect: function(well) {\n var flag;\n // check if not allow to add or delete existing wells\n if (this.disableAddDeleteWell) {\n var address = this.locToAddress({\n r: well.row,\n c: well.col\n });\n if (this.addressAllowToEdit.indexOf(address) < 0) {\n flag = false;\n this.setFieldsDisabled(true);\n } else {\n flag = true;\n this.setFieldsDisabled(false);\n }\n } else if (well) {\n flag = true;\n }\n\n if (flag) {\n var rect = this._areaToRect(this._wellToArea(well));\n var strokeWidth = 2;\n if (this.focalWellRect) {\n //update focalWellRect\n this.focalWellRect.top = rect.top;\n this.focalWellRect.left = rect.left;\n this.focalWellRect.width = rect.width - strokeWidth;\n this.focalWellRect.height = rect.height - strokeWidth;\n } else {\n //create focalWellRect\n this.focalWellRect = new fabric.Rect({\n width: rect.width - strokeWidth,\n height: rect.height - strokeWidth,\n left: rect.left,\n top: rect.top,\n fill: null,\n strokeWidth: strokeWidth,\n stroke: \"black\",\n selectable: false\n });\n this.mainFabricCanvas.add(this.focalWellRect);\n }\n } else {\n //clear focalWellRect\n this.mainFabricCanvas.remove(this.focalWellRect);\n this.focalWellRect = null;\n }\n },\n\n _setSelectedTiles: function() {\n // Update selected tile display only\n var selectedTiles = this.allSelectedObjects;\n this.allTiles.forEach(function(tile) {\n var selected = selectedTiles.indexOf(tile) >= 0;\n tile.highlight.visible = selected;\n })\n },\n\n _getSelectedWells: function () {\n var that = this; \n return this.allSelectedObjects.map(function (tile) {\n var well = that.engine.derivative[tile.index];\n if (!well) {\n well = that.defaultWell; \n }\n return well; \n }); \n },\n\n _getCommonFields: function (wells) {\n if (wells.length) {\n var referenceWell = wells[0];\n var referenceFields = $.extend(true, {}, referenceWell);\n for (var i = 1; i < wells.length; i++) {\n var fields = wells[i];\n for (var field in referenceFields) {\n if (Array.isArray(referenceFields[field])) {\n var refArr = referenceFields[field]; \n var agrArr = []; \n for (var j = 0; j < refArr.length; j++) {\n var v = refArr[j];\n if (v && typeof(v) === \"object\") {\n if (this.containsObject(v, fields[field])) {\n agrArr.push(v);\n }\n } else {\n if ($.inArray(v, fields[field]) >= 0) {\n agrArr.push(v);\n }\n }\n }\n referenceFields[field] = agrArr; \n } else {\n if (fields[field] && typeof(fields[field]) ===\"object\" && referenceFields[field] && typeof(referenceFields[field]) ===\"object\"){\n if ((fields[field].value !== referenceFields[field].value) || (fields[field].unit !== referenceFields[field].unit)){\n delete referenceFields[field];\n }\n } else if (referenceFields[field] != fields[field]) {\n delete referenceFields[field];\n }\n }\n }\n }\n return referenceFields\n } else {\n return {};\n }\n },\n\n containsObject: function(obj, list) {\n var equality = [];\n if (list) {\n list.forEach(function(val) {\n //evaluate val and obj\n var evaluate = [];\n Object.keys(val).forEach(function(listKey){\n if (Object.keys(obj).indexOf(listKey) >= 0){\n var curVal = val[listKey];\n if (typeof(curVal) === 'object' && curVal) {\n if (obj[listKey]){\n evaluate.push((curVal.unit === obj[listKey].unit) && (curVal.value === obj[listKey].value));\n } else {\n // when obj[listKey] is null but curVal is not\n evaluate.push(false);\n }\n } else {\n evaluate.push(curVal === obj[listKey]);\n }\n }\n });\n equality.push(evaluate.indexOf(false) < 0);\n });\n return equality.indexOf(true) >= 0;\n } else {\n return false;\n }\n },\n\n _getCommonWell: function (wells) {\n if (wells.length) {\n var referenceWell = wells[0];\n var referenceFields = $.extend(true, {}, referenceWell);\n for (var i = 1; i < wells.length; i++) {\n var well = wells[i];\n var fields = well;\n for (var field in referenceFields) {\n if (Array.isArray(referenceFields[field])) {\n var refArr = referenceFields[field]; \n var agrArr = []; \n for (var j = 0; j < refArr.length; j++) {\n var v = refArr[j];\n // for multiplex field\n if (typeof(refArr[j]) ===\"object\"){\n if (this.containsObject(v, fields[field])) {\n agrArr.push(v);\n }\n } else {\n if ($.inArray(v, fields[field]) >= 0) {\n agrArr.push(v);\n }\n }\n }\n referenceFields[field] = agrArr; \n } else {\n if (fields[field] && typeof(fields[field]) ===\"object\" && referenceFields[field] && typeof(referenceFields[field]) ===\"object\"){\n if ((fields[field].value !== referenceFields[field].value) || (fields[field].unit !== referenceFields[field].unit)){\n referenceFields[field] = null;\n }\n } else if (referenceFields[field] != fields[field]) {\n referenceFields[field] = null;\n }\n\n }\n }\n }\n return referenceFields;\n } else {\n return this.defaultWell; \n }\n }, \n\n _getAllMultipleVal: function (wells) {\n var multipleFieldList = this.multipleFieldList;\n\n multipleFieldList.forEach(function(multiplexField) {\n if(wells.length) {\n var curMultipleVal = {};\n wells.forEach(function (wellData) {\n var id = multiplexField.id;\n if (wellData[id]){\n if (wellData[id].length > 0) {\n wellData[id].forEach(function (multipleVal) {\n if (typeof(multipleVal) === 'object') {\n if (multipleVal[id] in curMultipleVal) {\n curMultipleVal[multipleVal[id]] ++;\n } else {\n curMultipleVal[multipleVal[id]] = 1;\n }\n } else {\n if (multipleVal in curMultipleVal) {\n curMultipleVal[multipleVal] ++;\n\n } else {\n curMultipleVal[multipleVal] = 1;\n }\n }\n })\n }\n }\n });\n multiplexField.allSelectedMultipleVal = curMultipleVal;\n } else {\n multiplexField.allSelectedMultipleVal = null\n }\n });\n },\n\n decideSelectedFields: function() {\n var wells = this._getSelectedWells();\n this._getAllMultipleVal(wells);\n this.applyFieldWarning(wells);\n var well = this._getCommonWell(wells); \n this._addDataToTabFields(well);\n },\n\n // get well value differences for each well in wellsHash\n getDifferentWellsVals: function(wellsHash) {\n var wells = [];\n for (var wellId in wellsHash){\n wells.push(wellsHash[wellId]);\n }\n var differentWellsVals = {};\n if (wells.length > 1){\n var commonWell = this._getCommonWell(wells);\n var allFieldVal = {};\n for (var fieldIdx in wellsHash[0]) {\n allFieldVal[fieldIdx] = [];\n }\n for (var wellIdx in wells){\n var diffWellVal = {};\n var curWellData = wells[wellIdx];\n for (var fieldId in curWellData) {\n var commonVal = commonWell[fieldId];\n var curVal = curWellData[fieldId];\n var newVal = null;\n if (Array.isArray(curVal)) {\n // get uncommonVal\n newVal = [];\n for (var idx = 0; idx < curVal.length; idx ++){\n var curMultiVal = curVal[idx];\n // multiplex field\n if (curMultiVal && typeof(curMultiVal === \"object\")){\n if (!this.containsObject(curMultiVal, commonVal)) {\n newVal.push(curMultiVal);\n if (!this.containsObject(curMultiVal, allFieldVal[fieldId])) {\n allFieldVal[fieldId].push(curMultiVal);\n }\n }\n } else {\n if (commonVal.indexOf(curMultiVal) >= 0) {\n newVal.push(curMultiVal);\n if (!allFieldVal[fieldId].indexOf(curMultiVal) >= 0) {\n allFieldVal[fieldId].push(curMultiVal);\n }\n }\n }\n }\n } else if (curVal && typeof(curVal) === \"object\"){\n if (commonVal && typeof(commonVal) ===\"object\"){\n if (!((curVal.value === commonVal.value) || (curVal.unit === commonVal.unit))){\n newVal = curVal;\n if (!this.containsObject(curVal, allFieldVal[fieldId])) {\n allFieldVal[fieldId].push(curVal);\n }\n }\n } else {\n newVal = curVal;\n if (!this.containsObject(curVal, allFieldVal[fieldId])) {\n allFieldVal[fieldId].push(curVal);\n }\n }\n } else if (curVal !== commonVal) {\n newVal = curVal;\n if (!allFieldVal[fieldId].indexOf(curVal) >= 0) {\n allFieldVal[fieldId].push(curVal);\n }\n }\n diffWellVal[fieldId] = newVal;\n }\n\n\n differentWellsVals[wellIdx] = diffWellVal;\n }\n\n // clean up step for fields that are empty\n for (var fieldId in allFieldVal) {\n if (allFieldVal[fieldId].length === 0) {\n for (var wellIdx in differentWellsVals){\n delete differentWellsVals[wellIdx][fieldId];\n }\n }\n }\n\n return differentWellsVals;\n } else if (wellsHash[0]) {\n var well = {};\n for (var fieldId in wellsHash[0]) {\n var curVal = wellsHash[0][fieldId];\n if (Array.isArray(curVal)){\n if (curVal.length > 0) {\n well[fieldId] = curVal\n }\n } else if (curVal){\n well[fieldId] = curVal;\n }\n }\n return {\n 0: well\n };\n }\n },\n\n // get all wells that has data\n getWellSetAddressWithData: function(){\n var address = [];\n var derivative = this.engine.derivative;\n for (var id in derivative){\n address.push(this.indexToAddress(id));\n }\n return address;\n }\n\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\nplateLayOutWidget.assets = function () {\n return {\n _assets: {\n doImg: '✓',\n dontImg: '',\n warningImg: '⚠'\n }\n };\n};\n","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.interface = function() {\n // interface holds all the methods to put the interface in place\n return {\n\n _createInterface: function() {\n\n var divIdentifier = '<div></div>';\n this.container = this._createElement(divIdentifier).addClass(\"plate-setup-wrapper\");\n this.topSection = this._createElement(divIdentifier).addClass(\"plate-setup-top-section\");\n\n this.topLeft = this._createElement(divIdentifier).addClass(\"plate-setup-top-left\");\n this.topRight = this._createElement(divIdentifier).addClass(\"plate-setup-top-right\");\n\n this.overLayContainer = this._createElement(divIdentifier).addClass(\"plate-setup-overlay-container\");\n this.canvasContainer = this._createElement(divIdentifier).addClass(\"plate-setup-canvas-container\");\n\n this._createOverLay();\n $(this.topLeft).append(this.overLayContainer);\n\n this._createCanvas();\n $(this.topLeft).append(this.canvasContainer);\n\n\n $(this.topSection).append(this.topLeft);\n $(this.topSection).append(this.topRight);\n\n $(this.container).append(this.topSection);\n $(this.element).append(this.container);\n\n this._initiateFabricCanvas();\n\n this._createTabAtRight();\n this._createTabs();\n\n this._placePresetTabs();\n // Bottom of the screen\n this._bottomScreen();\n // Canvas\n this._canvas();\n\n this.bottomForFirstTime();\n\n var that = this;\n this._setShortcuts();\n $(document.body).keyup(function(e) {\n that._handleShortcuts(e);\n });\n\n this._configureUndoRedoArray();\n },\n\n _createElement: function(element) {\n return $(element);\n },\n\n _setShortcuts: function () {\n var that = this; \n window.addEventListener(\"cut\", function (e) {\n if (document.activeElement == document.body) {\n that.copyCriteria();\n that.clearCriteria();\n e.preventDefault();\n }\n });\n window.addEventListener(\"copy\", function (e) {\n if (document.activeElement == document.body) {\n that.copyCriteria();\n e.preventDefault();\n }\n });\n window.addEventListener(\"paste\", function (e) {\n if (document.activeElement == document.body) {\n that.pasteCriteria();\n e.preventDefault();\n }\n });\n },\n\n _handleShortcuts: function(e) {\n if (document.activeElement === document.body) {\n if (e.keyCode == 46) {\n this.clearCriteria();\n e.preventDefault();\n } else if (e.ctrlKey || e.metaKey) {\n if (e.keyCode == 90) {\n if (e.shiftKey) {\n this.redo();\n } else {\n this.undo();\n }\n e.preventDefault();\n } else if (e.keyCode == 89) {\n this.redo();\n e.preventDefault();\n }\n }\n }\n },\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.loadPlate = function(THIS) {\n // Methods which look after data changes and stack up accordingly\n // Remember THIS points to plateLayOutWidget and 'this' points to engine\n return {\n\n getPlates: function (data) {\n //sanitize input\n var derivative = {}; \n for (var index in data.derivative) {\n var well = data.derivative[index]; \n derivative[index] = this.sanitizeWell(well); \n }\n\n var checkboxes = data.checkboxes || []; \n var selection = this.sanitizeAreas(data.selectedAreas, data.focalWell); \n\n var sanitized = {\n \"derivative\": derivative,\n \"checkboxes\": checkboxes,\n \"selectedAreas\": selection.selectedAreas,\n \"focalWell\": selection.focalWell\n }; \n\n this.setData(sanitized);\n }, \n\n sanitizeAreas: function (selectedAreas, focalWell) {\n var that = this; \n var rows = this.dimensions.rows;\n var cols = this.dimensions.cols;\n\n if (!selectedAreas) {\n selectedAreas = [];\n }\n if (selectedAreas.length) {\n selectedAreas = selectedAreas.map(function (area) {\n return {\n minCol: that._coordIndex(Math.min(area.minCol, area.maxCol), cols), \n minRow: that._coordIndex(Math.min(area.minRow, area.maxRow), rows), \n maxCol: that._coordIndex(Math.max(area.minCol, area.maxCol), cols), \n maxRow: that._coordIndex(Math.max(area.minRow, area.maxRow), rows)\n }; \n }); \n var area = selectedAreas[selectedAreas.length - 1];\n if (focalWell && !this._wellInArea(focalWell, area)) {\n focalWell = null;\n }\n if (!focalWell) {\n focalWell = {\n row: area.minRow,\n col: area.minCol\n };\n }\n } else {\n if (!focalWell) {\n focalWell = {\n row: 0,\n col: 0\n };\n }\n selectedAreas = [this._wellToArea(focalWell)];\n }\n return {\n selectedAreas: selectedAreas, \n focalWell: focalWell\n };\n }, \n\n sanitizeWell: function (well) {\n var newWell = {};\n for (var i = 0; i < this.fieldList.length; i++) {\n var field = this.fieldList[i];\n newWell[field.id] = field.parseValue(well[field.id]);\n }\n return newWell; \n }, \n\n setData: function(data) {\n this.engine.derivative = $.extend(true, {}, data.derivative);\n this.setCheckboxes(data.checkboxes);\n this.setSelection(data.selectedAreas, data.focalWell);\n this._colorMixer();\n this.decideSelectedFields();\n this.mainFabricCanvas.renderAll();\n },\n\n }\n }\n})(jQuery, fabric);","var GET_PLATES = 'getPlates';\nvar IS_READ_ONLY = 'isReadOnly';\nvar IS_DISABLE_ADD_DELETE_WELL = 'isDisableAddDeleteWell';\nvar GET_SELECTED_OBJECT = 'getSelectedObject';\nvar SETSELECTEDWELL = 'setSelectedWell';","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.overlay = function() {\n // overlay holds all the methods to put the part just above the canvas which contains all those\n // 'completion percentage' annd 'copy Criteria' button etc ...\n return {\n\n _createOverLay: function() {\n\n var that = this;\n this.overLayTextContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-overlay-text-container\");\n this.overLayTextContainer.text(\"Completion Percentage:\");\n this.overLayContainer.append(this.overLayTextContainer);\n this.overLayButtonContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-overlay-button-container\");\n this.overLayContainer.append(this.overLayButtonContainer);\n\n this.clearCriteriaButton = this._createElement(\"<button />\").addClass(\"plate-setup-button\");\n this.clearCriteriaButton.text(\"Clear\");\n this.overLayButtonContainer.append(this.clearCriteriaButton);\n\n this.clearCriteriaButton.click(function(evt) {\n that.clearCriteria();\n });\n\n this.copyCriteriaButton = this._createElement(\"<button />\").addClass(\"plate-setup-button\");\n this.copyCriteriaButton.text(\"Copy\");\n this.overLayButtonContainer.append(this.copyCriteriaButton);\n\n this.copyCriteriaButton.click(function(evt) {\n that.copyCriteria();\n });\n\n this.pasteCriteriaButton = this._createElement(\"<button />\").addClass(\"plate-setup-button\");\n this.pasteCriteriaButton.text(\"Paste\");\n this.overLayButtonContainer.append(this.pasteCriteriaButton);\n\n this.pasteCriteriaButton.click(function(evt) {\n that.pasteCriteria();\n });\n\n this.undoButton = this._createElement(\"<button />\").addClass(\"plate-setup-button\");\n this.undoButton.text(\"Undo\");\n this.overLayButtonContainer.append(this.undoButton);\n\n this.undoButton.click(function(evt) {\n that.undo();\n });\n\n this.redoButton = this._createElement(\"<button />\").addClass(\"plate-setup-button\");\n this.redoButton.text(\"Redo\");\n this.overLayButtonContainer.append(this.redoButton);\n\n this.redoButton.click(function(evt) {\n that.redo();\n });\n\n },\n\n clearCriteria: function() {\n if (this.allSelectedObjects) {\n var noOfSelectedObjects = this.allSelectedObjects.length;\n var hasWellUpdate = false;\n for (var objectIndex = 0; objectIndex < noOfSelectedObjects; objectIndex++) {\n var tile = this.allSelectedObjects[objectIndex];\n if (tile.index in this.engine.derivative) {\n // handling for clearing well when not allowed to add or delete wells\n if (this.emptyWellWithDefaultVal && this.disableAddDeleteWell) {\n var well = JSON.parse(JSON.stringify(this.defaultWell));\n var defaultValue = this.emptyWellWithDefaultVal;\n for (var key in defaultValue){\n if (key in well) {\n well[key] = defaultValue[key];\n this._applyFieldData(key, defaultValue[key]);\n } else {\n console.log(\"Well does not contain key: \" + key + \", please contact support\");\n }\n }\n this.engine.derivative[tile.index] = well;\n } else {\n delete this.engine.derivative[tile.index];\n }\n hasWellUpdate = true;\n }\n }\n if (hasWellUpdate){\n this.derivativeChange();\n }\n\n this._colorMixer();\n this.decideSelectedFields();\n } else {\n alert(\"Please select any well\");\n }\n },\n\n copyCriteria: function() {\n if (this.allSelectedObjects) {\n var wells = this._getSelectedWells(); \n this.commonWell = this._getCommonFields(wells); \n } else {\n alert(\"Please select any well.\");\n }\n },\n\n pasteCriteria: function() {\n if (this.commonWell) {\n this._addAllData(this.commonWell);\n this.decideSelectedFields();\n this.mainFabricCanvas.renderAll();\n }\n }\n };\n }\n})(jQuery, fabric);","$.widget(\"DNA.plateLayOut\", {\n\n plateLayOutWidget: {},\n\n options: {\n value: 0\n },\n\n allTiles: [], // All tiles containes all thise circles in the canvas\n\n addressToLoc: function (layoutAddress) {\n var m = /^([A-Z]+)(\\d+)$/.exec(layoutAddress.trim().toUpperCase())\n if (m) {\n var row_v = m[1]; \n var col = parseInt(m[2])-1;\n var row; \n for (var i = 0; i < row_v.length; i++) {\n var c = row_v.charCodeAt(i) - 65; \n if (i) {\n row += 1;\n row *= 26; \n row += c ; \n } else {\n row = c;\n }\n }\n return {\n r: row, \n c: col\n };\n } else {\n throw layoutAddress + \" not a proper layout address\"; \n }\n },\n\n locToIndex: function (loc, dimensions) {\n if (!dimensions) {\n dimensions = this.dimensions;\n }\n if (loc.r < 0) {\n t\n }\n if (!(loc.r >= 0 && loc.r < dimensions.rows)) {\n throw \"Row index \" + (loc.r + 1) + \" invalid\"; \n }\n if (!(loc.c >= 0 && loc.c < dimensions.cols)) {\n throw \"Column index \" + (loc.c + 1) + \" invalid\"; \n }\n return loc.r*dimensions.cols + loc.c; \n },\n\n addressToIndex: function (layoutAddress, dimensions) {\n var loc = this.addressToLoc(layoutAddress); \n return this.locToIndex(loc, dimensions); \n }, \n\n _rowKey: function (i) {\n var c1 = i % 26;\n var c2 = (i - c1) / 26;\n var code = String.fromCharCode(65 + c1);\n if (c2 > 0) {\n code = String.fromCharCode(64 + c2) + code;\n }\n return code;\n }, \n\n indexToLoc: function (index, dimensions) {\n if (!dimensions) {\n dimensions = this.dimensions;\n }\n\n if (index >= dimensions.rows * dimensions.cols) {\n throw \"Index too high: \" + index.toString(10); \n }\n var loc = {}; \n loc.c = index % dimensions.cols;\n loc.r = (index - loc.c) / dimensions.cols;\n\n return loc; \n },\n\n locToAddress: function (loc) {\n return this._rowKey(loc.r) + (loc.c + 1).toString(10);\n },\n\n indexToAddress: function (index, dimensions) {\n var loc = this.indexToLoc(index, dimensions); \n return this.locToAddress(loc); \n },\n\n getDimensions: function () {\n return $.extend(true, {}, this.dimensions);\n },\n\n _create: function() {\n var rows = parseInt(this.options.numRows || 8);\n var cols = parseInt(this.options.numCols || 12);\n this.dimensions = {\n rows: rows,\n cols: cols\n };\n this.rowIndex = [];\n for (var i = 0; i < rows; i++) {\n this.rowIndex.push(this._rowKey(i));\n }\n\n this.target = (this.element[0].id) ? \"#\" + this.element[0].id : \".\" + this.element[0].className;\n\n // Import classes from other files.. Here we import it using extend and add it to this\n // object. internally we add to widget.DNA.getPlates.prototype.\n // Helpers are methods which return other methods and objects.\n // add Objects to plateLayOutWidget and it will be added to this object.\n // set read only well\n if (this.options.readOnly){\n this.isReadOnly(true);\n }\n\n for (var component in plateLayOutWidget) {\n // Incase some properties has to initialize with data from options hash,\n // we provide it sending this object.\n $.extend(this, new plateLayOutWidget[component](this));\n }\n\n this.imgSrc = this.options.imgSrc || \"assets\";\n\n this._createInterface();\n\n this._trigger(\"created\", null, this);\n\n return this;\n },\n\n _init: function() {\n // This is invoked when the user use the plugin after _create is called.\n // The point is _create is invoked for the very first time and for all other\n // times _init is used.\n },\n\n addData: function() {\n alert(\"wow this is good\");\n },\n\n // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}}\n getTextDerivative: function(wellsData) {\n var textDerivative = {};\n var fieldMap = this.fieldMap;\n for (var idx in wellsData){\n var textValWell = {};\n var textFieldIdWell = {};\n var curWellData = wellsData[idx];\n for (var fieldId in curWellData){\n if (fieldId in this.fieldMap){\n var field = this.fieldMap[fieldId];\n var textVal = field.parseText(curWellData[fieldId]);\n textFieldIdWell[field.name] = textVal;\n textValWell[fieldId] = textVal;\n } else {\n // do not convert if not a field (ex: layout_address)\n textFieldIdWell[fieldId] = curWellData[fieldId];\n textValWell[fieldId] = curWellData[fieldId];\n }\n }\n textDerivative[idx] = {\n textVal: textValWell,\n textFieldVal: textFieldIdWell\n };\n }\n\n return textDerivative;\n },\n\n // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}}\n getWellsDifferences: function(wellsData) {\n return this.getDifferentWellsVals(wellsData);\n },\n\n setFieldsDisabled: function(flag){\n this.fieldList.forEach(function(field){\n field.disabled(flag);\n });\n },\n\n isReadOnly: function(flag){\n if (flag){\n this.readOnly = true;\n } else {\n this.readOnly = false;\n }\n this.readOnlyHandler();\n },\n\n readOnlyHandler: function(){\n if (this.readOnly){\n this.overLayButtonContainer.css(\"display\", \"none\");\n $('.multiple-field-manage-delete-button').css(\"display\", \"none\");\n this.setFieldsDisabled(true);\n } else {\n this.overLayButtonContainer.css(\"display\", \"flex\");\n $('.multiple-field-manage-delete-button').css(\"display\", \"none\");\n if (!this.disableAddDeleteWell) {\n this.setFieldsDisabled(false);\n }\n }\n },\n\n disableAddDeleteWell: null,\n // column_with_default_val will be used to determine empty wells, format: {field_name: default_val}\n isDisableAddDeleteWell: function(flag, column_with_default_val){\n if (flag){\n this.disableAddDeleteWell = true;\n this.addressAllowToEdit = this.getWellSetAddressWithData();\n // configure undo redo action\n this.actionPointer = 0;\n this.undoRedoArray = [];\n this.undoRedoArray.push(this.createObject());\n if (column_with_default_val) {\n this.emptyWellWithDefaultVal = column_with_default_val;\n }\n } else {\n this.disableAddDeleteWell = false;\n this.setFieldsDisabled(false);\n this.emptyWellWithDefaultVal = null;\n }\n this._fabricEvents();\n },\n\n getSelectedObject: function() {\n var selectedAddress = [];\n for (var i = 0; i < this.allSelectedObjects.length; i++){\n selectedAddress.push(this.allSelectedObjects[i].address);\n }\n var selectedObjects = {};\n var derivative = this.engine.derivative;\n for (var loc in derivative){\n var address = this.indexToAddress(loc);\n if (selectedAddress.indexOf(address) >= 0) {\n selectedObjects[address] = derivative[loc];\n }\n }\n return selectedObjects;\n },\n\n getSelectedIndex: function() {\n return this.allSelectedObjects.map(function(selectedObj){\n return that.addressToIndex(selectedObj.address)\n });\n },\n\n getSelectedAddress: function() {\n return this.allSelectedObjects.map(function(selectedObj){\n return selectedObj.address;\n });\n },\n\n setSelectedWell: function(addressList) {\n var areas = [];\n var minRow = 999;\n var locMap = {};\n for (var id = 0; id < addressList.length; id++){\n var wellIdx = this.addressToIndex(addressList[id]);\n var loc = this.indexToLoc(wellIdx);\n areas.push({\n minCol: loc.c,\n minRow: loc.r,\n maxCol: loc.c,\n maxRow: loc.r\n });\n if (loc.r <= minRow) {\n minRow = loc.r;\n if (loc.r in locMap) {\n locMap[loc.r].push(loc.c);\n } else {\n locMap[loc.r] = [loc.c];\n }\n }\n }\n var focalWell = {\n row: minRow,\n col: Math.min.apply(null, locMap[minRow])\n };\n\n this.setSelection(areas, focalWell);\n this.decideSelectedFields();\n this.mainFabricCanvas.renderAll();\n }\n\n});","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.preset = function(me) {\n // All the preset action goes here\n return {\n\n presets: [],\n\n _placePresetTabs: function() {\n var presets = this.options.attributes.presets;\n\n if (presets && presets.length) {\n this.wellAttrContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-well-attr-container\")\n .text(\"Checkbox presets\");\n this.tabContainer.append(this.wellAttrContainer);\n\n this.presetTabContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-preset-container\");\n this.tabContainer.append(this.presetTabContainer);\n\n for (var i = 0; i < presets.length; i++) {\n var preset = presets[i];\n var divText = this._createElement(\"<div></div>\").addClass(\"plate-setup-prest-tab-div\")\n .text(preset.title);\n\n var presetButton = this._createElement(\"<div></div>\").addClass(\"plate-setup-prest-tab\")\n .data(\"preset\", preset.fields).append(divText);\n this.presetTabContainer.append(presetButton);\n\n var that = this;\n presetButton.click(function() {\n var preset = $(this);\n that._selectPreset(preset);\n });\n this.presets.push(presetButton);\n }\n }\n },\n\n _clearPresetSelection: function() {\n for (var j = 0; j < this.presets.length; j++) {\n var p = this.presets[j]; \n p.removeClass(\"plate-setup-prest-tab-selected\")\n .addClass(\"plate-setup-prest-tab\"); \n }\n },\n\n _selectPreset: function (preset) {\n this.setCheckboxes(preset.data(\"preset\")); \n preset.removeClass(\"plate-setup-prest-tab\")\n .addClass(\"plate-setup-prest-tab-selected\");\n },\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.tabs = function() {\n // Tabs crete and manage tabs at the right side of the canvas.\n return {\n\n allTabs: [],\n\n defaultWell: {},\n\n allDataTabs: [], // To hold all the tab contents. this contains all the tabs and its elements and elements\n // Settings as a whole. its very usefull, when we have units for a specific field.\n // it goes like tabs-> individual field-> units and checkbox\n\n _createTabAtRight: function() {\n this.tabContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-tab-container\");\n $(this.topRight).append(this.tabContainer);\n },\n\n _createTabs: function() {\n // this could be done using z-index. just imagine few cards stacked up.\n // Check if options has tab data.\n // Originally we will be pulling tab data from developer.\n // Now we are building upon dummy data.\n this.tabHead = this._createElement(\"<div></div>\").addClass(\"plate-setup-tab-head\");\n $(this.tabContainer).append(this.tabHead);\n\n var tabData = this.options.attributes.tabs;\n var that = this;\n\n tabData.forEach(function (tab, tabIndex) {\n that.allTabs[tabIndex] = that._createElement(\"<div></div>\").addClass(\"plate-setup-tab\");\n $(that.allTabs[tabIndex]).data(\"index\", tabIndex)\n .text(tab.name);\n\n $(that.allTabs[tabIndex]).click(function() {\n that._tabClickHandler(this);\n });\n\n $(that.tabHead).append(that.allTabs[tabIndex]);\n }); \n\n this.tabDataContainer = this._createElement(\"<div></div>\").addClass(\"plate-setup-tab-data-container\");\n $(this.tabContainer).append(this.tabDataContainer);\n\n this._addDataTabs(tabData);\n\n $(this.allTabs[0]).click();\n\n this._addTabData();\n },\n\n _tabClickHandler: function(clickedTab) {\n\n if (this.selectedTab) {\n $(this.selectedTab).removeClass(\"plate-setup-tab-selected\")\n .addClass(\"plate-setup-tab\");\n\n var previouslyClickedTabIndex = $(this.selectedTab).data(\"index\");\n $(this.allDataTabs[previouslyClickedTabIndex]).css(\"z-index\", 0);\n this.readOnlyHandler();\n }\n\n $(clickedTab).addClass(\"plate-setup-tab-selected\");\n\n this.selectedTab = clickedTab;\n\n var clickedTabIndex = $(clickedTab).data(\"index\");\n $(this.allDataTabs[clickedTabIndex]).css(\"z-index\", 1000);\n },\n\n _addDataTabs: function(tabs) {\n\n var tabIndex = 0;\n\n for (var tabData in tabs) {\n this.allDataTabs[tabIndex++] = this._createElement(\"<div></div>\").addClass(\"plate-setup-data-div\")\n .css(\"z-index\", 0);\n $(this.tabDataContainer).append(this.allDataTabs[tabIndex - 1]);\n }\n }\n };\n }\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.undoRedoManager = function(THIS) {\n\n return {\n\n undoRedoArray: [],\n\n actionPointer: null,\n\n addToUndoRedo: function(data) {\n\n if (this.actionPointer != null) {\n var i = this.actionPointer + 1; \n if (i < this.undoRedoArray.length) {\n this.undoRedoArray.splice(i, this.undoRedoArray.length - i);\n }\n }\n this.actionPointer = null;\n this.undoRedoArray.push($.extend(true, {}, data));\n },\n\n _configureUndoRedoArray: function() {\n\n var data = {\n checkboxes: [],\n derivative: {},\n selectedAreas: [{\n minRow: 0,\n minCol: 0,\n maxRow: 0,\n maxCol: 0\n }],\n focalWell: {\n row: 0,\n col: 0\n }\n };\n\n this.undoRedoArray = []; \n this.actionPointer = null; \n this.undoRedoArray.push($.extend({}, data));\n },\n\n undo: function() {\n console.log(\"undo\");\n return this.shiftUndoRedo(-1); \n },\n\n redo: function() {\n console.log(\"redo\");\n return this.shiftUndoRedo(1); \n }, \n\n shiftUndoRedo: function (pointerDiff) {\n var pointer = this.actionPointer;\n if (pointer == null) {\n pointer = this.undoRedoArray.length - 1; \n }\n pointer += pointerDiff; \n return this.setUndoRedo(pointer); \n }, \n\n setUndoRedo: function (pointer) {\n if (pointer < 0) {\n return false; \n }\n if (pointer >= this.undoRedoArray.length) {\n return false; \n }\n this.undoRedoActive = true; \n this.setData(this.undoRedoArray[pointer]);\n this.actionPointer = pointer; \n this.undoRedoActive = false;\n this.derivativeChange();\n return true;\n }\n }\n };\n\n})(jQuery, fabric);","var plateLayOutWidget = plateLayOutWidget || {};\n\n(function($, fabric) {\n\n plateLayOutWidget.wellArea = function(fabric) {\n\n return {\n\n _areasToTiles: function(areas) {\n //Convert areas to tiles\n var cols = this.dimensions.cols;\n var that = this;\n return areas.reduce(function(tiles, area) {\n if (area) {\n for (var r = area.minRow; r <= area.maxRow; r++) {\n for (var c = area.minCol; c <= area.maxCol; c++) {\n var tile = that.allTiles[c + cols * r];\n if (tiles.indexOf(tile) < 0) {\n if (that.disableAddDeleteWell){\n if(that.addressAllowToEdit.indexOf(tile.address) >= 0){\n tiles.push(tile);\n }\n } else {\n tiles.push(tile);\n }\n }\n }\n }\n }\n return tiles;\n }, []);\n },\n\n _encodeArea: function(area) {\n //Encode area as string\n if ((area.minRow == area.maxRow) && (area.minCol == area.maxCol)) {\n return this.rowIndex[area.minRow] + area.minCol.toString(10);\n } else {\n return this.rowIndex[area.minRow] + area.minCol.toString(10) + \":\" + this.rowIndex[area.maxRow] + area.maxCol.toString(10);\n }\n },\n\n _encodeAreas: function(areas) {\n //Encode an array of areas as a string\n var that = this;\n return areas.map(function(area) {\n return that._encodeArea(area);\n }).join(\",\");\n },\n\n _decodeWell: function(wellAddress) {\n var that = this;\n var adRx = new RegExp(\"^\\\\s*(\" + that.rowIndex.join(\"|\") + \")(\\\\d+)\\\\s*$\")\n var rcRx = /^\\s*R(\\d+)C(\\d+)\\s*$/i;\n\n var match;\n match = wellAddress.match(adRx);\n if (match) {\n var row = that.rowIndex.indexOf(match[1]);\n if (row >= 0) {\n return {\n row: row,\n col: parseInt(match[2]) - 1\n };\n }\n }\n match = wellAddress.match(rcRx);\n if (match) {\n return {\n row: parseInt(match[1]) - 1,\n col: parseInt(match[2]) - 1\n };\n }\n\n throw \"Invalid well address: \" + wellAddress;\n },\n\n _decodeArea: function(areaAddress) {\n //Decode single area as string\n var that = this;\n var wells = areaAddress.split(\":\").map(function(wellAddress) {\n return that._decodeWell(wellAddress);\n })\n if (wells.length == 1) {\n return {\n minRow: wells[0].row,\n minCol: wells[0].col,\n maxRow: wells[0].row,\n maxCol: wells[0].col\n }\n } else if (wells.length == 2) {\n var minRow = Math.min(wells[0].row, wells[1].row)\n return {\n minRow: Math.min(wells[0].row, wells[1].row),\n minCol: Math.min(wells[0].col, wells[1].col),\n maxRow: Math.max(wells[0].row, wells[1].row),\n maxCol: Math.max(wells[0].col, wells[1].col)\n }\n } else {\n throw \"Invalid address: \" + areaAddress;\n }\n },\n\n _decodeAreas: function(areasAddress) {\n //Decode single area as string\n var that = this;\n return areasAddress.split(\",\").map(function(areaAddress) {\n return that._decodeArea(areaAddress);\n });\n },\n\n _wellToArea: function(well) {\n //Convert a well to an area\n return {\n minCol: well.col,\n minRow: well.row,\n maxCol: well.col,\n maxRow: well.row\n }\n },\n\n _wellInArea: function(well, area) {\n //Determine if a well lies within an area\n return well.row >= area.minRow && well.row <= area.maxRow && well.col >= area.minCol && well.col <= area.maxCol;\n },\n\n _coordsToRect: function(startCoords, endCoords) {\n //Convert two XY coords to a bounding box\n var left = Math.min(startCoords.x, endCoords.x);\n var top = Math.min(startCoords.y, endCoords.y);\n var height = Math.abs(endCoords.y - startCoords.y);\n var width = Math.abs(endCoords.x - startCoords.x);\n return {\n top: top,\n left: left,\n height: height,\n width: width\n };\n },\n\n _coordIndex: function(v, count) {\n var i;\n if (v < 0) {\n i = 0;\n } else if (v >= count) {\n i = count - 1;\n } else {\n i = Math.floor(v);\n }\n return i;\n },\n\n _coordsToWell: function(coord) {\n //Convert a coordinate to a well\n var cols = this.dimensions.cols;\n var rows = this.dimensions.rows;\n\n var w = this.sizes.spacing; \n var m = this.sizes.label_spacing; \n\n var x = (coord.x - m) / w;\n var y = (coord.y - m) / w;\n\n var row = this._coordIndex(y, rows);\n var col = this._coordIndex(x, cols);\n\n return {\n row: row,\n col: col,\n };\n },\n\n _wellToCoords: function(well, center) {\n //Convert a well to a coordinate\n var w = this.sizes.spacing; \n var m = this.sizes.label_spacing; \n var x = well.col * w + m;\n var y = well.row * w + m;\n if (center) {\n var hw = w/2;\n x = x + hw;\n y = y + hw;\n }\n\n return {\n x: x,\n y: y\n };\n },\n\n _areaToRect: function(area) {\n //Convert area to rectangle\n var rows = area.maxRow - area.minRow + 1;\n var cols = area.maxCol - area.minCol + 1;\n\n var w = this.sizes.spacing; \n var m = this.sizes.label_spacing; \n\n return {\n top: area.minRow * w + m,\n left: area.minCol * w + m,\n height: rows * w,\n width: cols * w\n }\n },\n\n _rectToArea: function(rect) {\n //Convert a rectangular region to an area\n var rows = this.dimensions.rows;\n var cols = this.dimensions.cols;\n\n var w = this.sizes.spacing; \n var m = this.sizes.label_spacing; \n\n var left = (rect.left - m) / w;\n var top = (rect.top - m) / w;\n var height = rect.height / w;\n var width = rect.width / w;\n var right = left + width;\n var bottom = top + height;\n\n //select whole row\n if (right < 0) {\n right = cols;\n }\n if (left >= cols) {\n left = 0;\n }\n //select whole col\n if (bottom < 0) {\n bottom = rows;\n }\n if (top <= 0) {\n top = 0;\n }\n\n return {\n minCol: this._coordIndex(left, cols),\n minRow: this._coordIndex(top, rows),\n maxCol: this._coordIndex(right, cols),\n maxRow: this._coordIndex(bottom, rows)\n };\n }\n\n }\n }\n})(jQuery, fabric);"]} \ No newline at end of file diff --git a/dist/package.json b/dist/package.json deleted file mode 100644 index 4f0efc3..0000000 --- a/dist/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "plate-map", - "version": "1.0.2", - "description": "JavaScript Plate Layout is an open source tool developed collaboratively by [Chai Biotechnologies](www.chaibio.com) and [New England Biolabs](www.neb.com) for visualizing and editing the layout of scientific assay plates.", - "scripts": { - "build.dist": "gulp build.dist", - "build.dev": "gulp build.dev", - "serve.dev": "gulp serve.dev", - "build.prod": "gulp build.prod", - "serve.prod": "gulp serve.prod", - "start": "gulp serve.dev" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/nebiolabs/plate-map.git" - }, - "main": "dist/js/plate-map.js", - "style": "dist/css/plate-map.css", - "keywords": [], - "author": "Langhorst, Brad <Langhorst@neb.com>", - "license": "AGPL-3.0-only", - "bugs": { - "url": "https://github.com/nebiolabs/plate-map/issues" - }, - "homepage": "https://github.com/nebiolabs/plate-map#readme", - "dependencies": { - "bootstrap": "^4.1.3", - "clipboard": "^2.0.4", - "fabric": "^2.6.0", - "jquery": "^3.3.1", - "jquery-ui-dist": "^1.12.1", - "popper.js": "^1.14.7", - "select2": "^3.5.1" - }, - "devDependencies": { - "browser-sync": "^2.26.3", - "del": "^3.0.0", - "gulp": "^4.0.0", - "gulp-clean-css": "^4.0.0", - "gulp-concat": "^2.6.1", - "gulp-connect": "^5.7.0", - "gulp-htmlmin": "^5.0.1", - "gulp-inject": "^5.0.2", - "gulp-rename": "^1.4.0", - "gulp-uglify": "^3.0.1", - "merge-stream": "^1.0.1", - "run-sequence": "^2.2.1" - } -} diff --git a/src/js/plate-layout.js b/src/js/plate-layout.js index 87bf4ec..dae3e5f 100755 --- a/src/js/plate-layout.js +++ b/src/js/plate-layout.js @@ -121,8 +121,6 @@ $.widget("DNA.plateLayOut", { $.extend(this, new plateLayOutWidget[component](this)); } - this.imgSrc = this.options.imgSrc || "assets"; - this._createInterface(); this._trigger("created", null, this); From 45738844f9284331bff5ac999580f7d0d7da4ef7 Mon Sep 17 00:00:00 2001 From: Zahen Malla Osman <zahen.malla-osman@abolis.fr> Date: Thu, 21 Mar 2019 09:47:34 +0100 Subject: [PATCH 06/10] Indent JS files with 2-spaces + rm stackPointer param from setTileColor() --- src/js/add-data-on-change.js | 42 +-- src/js/add-data-to-tabs.js | 2 +- src/js/add-tab-data.js | 171 ++++----- src/js/add-warning-msg.js | 26 +- src/js/bottom-table.js | 10 +- src/js/canvas.js | 16 +- src/js/color-manager.js | 2 +- src/js/create-canvas-elements.js | 92 ++--- src/js/create-field.js | 83 +++-- src/js/engine.js | 32 +- src/js/example.js | 400 ++++++++++---------- src/js/fabric-events.js | 100 ++--- src/js/image_assets.js | 16 +- src/js/interface.js | 10 +- src/js/load-plate.js | 42 +-- src/js/overlay.js | 8 +- src/js/plate-layout.js | 612 +++++++++++++++---------------- src/js/preset.js | 8 +- src/js/tabs.js | 4 +- src/js/undo-redo-manager.js | 32 +- src/js/well-area.js | 22 +- 21 files changed, 868 insertions(+), 862 deletions(-) diff --git a/src/js/add-data-on-change.js b/src/js/add-data-on-change.js index d756755..5434171 100755 --- a/src/js/add-data-on-change.js +++ b/src/js/add-data-on-change.js @@ -17,8 +17,8 @@ var plateLayOutWidget = plateLayOutWidget || {}; if (tile.index in this.engine.derivative) { well = this.engine.derivative[tile.index]; } else { - well = $.extend(true, {}, this.defaultWell); - this.engine.derivative[tile.index] = well; + well = $.extend(true, {}, this.defaultWell); + this.engine.derivative[tile.index] = well; } var processedData = this.processWellData(data, well, noOfSelectedObjects, wells); wells = processedData.wells; @@ -28,8 +28,8 @@ var plateLayOutWidget = plateLayOutWidget || {}; if (this.emptyWellWithDefaultVal && this.disableAddDeleteWell) { var wellCopy = JSON.parse(JSON.stringify(well)); var defaultValue = this.emptyWellWithDefaultVal; - for (var key in defaultValue){ - if (key in wellCopy){ + for (var key in defaultValue) { + if (key in wellCopy) { wellCopy[key] = defaultValue[key]; this._applyFieldData(key, defaultValue[key]); } @@ -51,13 +51,13 @@ var plateLayOutWidget = plateLayOutWidget || {}; processWellData: function(newData, curWell, noOfSelectedObjects, wellList) { - if (!wellList){ + if (!wellList) { wellList = []; } for (var id in newData) { var v; - if (newData[id] !== undefined && newData[id] !== null ) { - if (newData[id].multi){ + if (newData[id] !== undefined && newData[id] !== null) { + if (newData[id].multi) { var curData = newData[id]; var preData = curWell[id]; var newDt = this._getMultiData(preData, curData, id, noOfSelectedObjects); @@ -83,7 +83,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; var addNew = curData.added; var removed = curData.removed; if (addNew) { - if (preData){ + if (preData) { if (addNew.value) { var add = true; for (var listIdx in preData) { @@ -96,7 +96,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; if (val[fieldId].toString() === addNew.id.toString()) { for (var subFieldId in val) { // over write previous data if only one well is selected - if (subFieldId in addNew.value && subFieldId !== fieldId){ + if (subFieldId in addNew.value && subFieldId !== fieldId) { if (noOfSelectedObjects === 1) { val[subFieldId] = addNew.value[subFieldId]; } else if (addNew.value[subFieldId]) { @@ -119,7 +119,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; preData = []; if (addNew.value) { preData.push(addNew.value); - } else if (addNew){ + } else if (addNew) { preData.push(addNew); } } @@ -128,7 +128,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; var removeListIndex = function(preData, removeIndex) { var newPreData = []; for (var idx in preData) { - if (parseInt(idx) !== parseInt(removeIndex)){ + if (parseInt(idx) !== parseInt(removeIndex)) { newPreData.push(preData[idx]); } } @@ -148,7 +148,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; // remove nested element preData = removeListIndex(preData, removeIndex); } else { - if (preData){ + if (preData) { removeIndex = preData.indexOf(removed); if (removeIndex >= 0) { preData = removeListIndex(preData, removeIndex); @@ -157,29 +157,29 @@ var plateLayOutWidget = plateLayOutWidget || {}; } } if (preData && (preData.length == 0)) { - preData = null; + preData = null; } return preData }, _colorMixer: function() { if (!this.undoRedoActive) { - var data = this.createObject(); - this.addToUndoRedo(data); + var data = this.createObject(); + this.addToUndoRedo(data); } - this.engine.searchAndStack(); + this.engine.searchAndStack(); this.engine.applyColors(); this.mainFabricCanvas.renderAll(); }, - derivativeChange: function(){ - this._trigger("updateWells", null, this.createObject()); + derivativeChange: function() { + this._trigger("updateWells", null, this.createObject()); }, createObject: function() { - var derivative = $.extend(true, {}, this.engine.derivative); - var checkboxes = this.globalSelectedAttributes.slice(); - var selectedAreas = this.selectedAreas.slice(); + var derivative = $.extend(true, {}, this.engine.derivative); + var checkboxes = this.globalSelectedAttributes.slice(); + var selectedAreas = this.selectedAreas.slice(); var focalWell = this.focalWell; return { diff --git a/src/js/add-data-to-tabs.js b/src/js/add-data-to-tabs.js index 095a29e..9f4ad50 100755 --- a/src/js/add-data-to-tabs.js +++ b/src/js/add-data-to-tabs.js @@ -14,7 +14,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; }, _applyFieldData: function(id, v) { - this.fieldMap[id].setValue(v); + this.fieldMap[id].setValue(v); } } } diff --git a/src/js/add-tab-data.js b/src/js/add-tab-data.js index 1bc7c44..c08e86a 100755 --- a/src/js/add-tab-data.js +++ b/src/js/add-tab-data.js @@ -6,55 +6,56 @@ var plateLayOutWidget = plateLayOutWidget || {}; return { - fieldList: [], + fieldList: [], fieldMap: {}, autoId: 1, _addTabData: function() { - // Here we may need more changes because attributes format likely to change - var tabData = this.options.attributes.tabs; - var that = this; - this.requiredField = []; - var multiplexFieldArray = []; - tabData.forEach(function (tab, tabPointer) { - if (tab["fields"]) { - var tabFields = tab["fields"]; - var fieldArray = []; - var fieldArrayIndex = 0; - // Now we look for fields in the json - for (var field in tabFields) { - var data = tabFields[field]; - - if (!data.id) { - data.id = "Auto" + that.autoId++; - console.log("Field autoassigned id " + data.id); - } - if (!data.type) { - data.type = "text"; - console.log("Field " + data.id + " autoassigned type " + data.type); - } + // Here we may need more changes because attributes format likely to change + var tabData = this.options.attributes.tabs; + var that = this; + this.requiredField = []; + var multiplexFieldArray = []; + tabData.forEach(function(tab, tabPointer) { + if (tab["fields"]) { + var tabFields = tab["fields"]; + var fieldArray = []; + var fieldArrayIndex = 0; + // Now we look for fields in the json + for (var field in tabFields) { + var data = tabFields[field]; + + if (!data.id) { + data.id = "Auto" + that.autoId++; + console.log("Field autoassigned id " + data.id); + } + if (!data.type) { + data.type = "text"; + console.log("Field " + data.id + " autoassigned type " + data.type); + } - var field_val; - if (data.type === "multiplex") { - field_val = that._makeMultiplexField(data, tabPointer, fieldArray); + var field_val; + if (data.type === "multiplex") { + field_val = that._makeMultiplexField(data, tabPointer, fieldArray); + multiplexFieldArray.push(field_val); + } else { + field_val = that._makeRegularField(data, tabPointer, fieldArray, true); + if (data.type === "multiselect") { multiplexFieldArray.push(field_val); - } else { - field_val = that._makeRegularField(data, tabPointer, fieldArray, true); - if (data.type === "multiselect") { - multiplexFieldArray.push(field_val); - } - }; + } } - - that.allDataTabs[tabPointer]["fields"] = fieldArray; - } else { - console.log("unknown format in field initialization"); + ; } - }); - that.multipleFieldList = multiplexFieldArray; + + that.allDataTabs[tabPointer]["fields"] = fieldArray; + } else { + console.log("unknown format in field initialization"); + } + }); + that.multipleFieldList = multiplexFieldArray; }, - _makeSubField: function (data, tabPointer, fieldArray) { + _makeSubField: function(data, tabPointer, fieldArray) { var that = this; if (!data.id) { data.id = "Auto" + that.autoId++; @@ -90,52 +91,52 @@ var plateLayOutWidget = plateLayOutWidget || {}; return field; }, - _makeRegularField: function (data, tabPointer, fieldArray, checkbox){ - var that = this; - var wrapperDiv = that._createElement("<div></div>").addClass("plate-setup-tab-default-field"); - var wrapperDivLeftSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"); - var wrapperDivRightSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-right-side "); - var nameContainer = that._createElement("<div></div>").addClass("plate-setup-tab-name").text(data.name); - var fieldContainer = that._createElement("<div></div>").addClass("plate-setup-tab-field-container"); - - wrapperDivRightSide.append(nameContainer); - wrapperDivRightSide.append(fieldContainer); - wrapperDiv.append(wrapperDivLeftSide); - wrapperDiv.append(wrapperDivRightSide); - that.allDataTabs[tabPointer].append(wrapperDiv); - - var field = { - id: data.id, - name: data.name, - root: wrapperDiv, - data: data, - required: data.required - }; + _makeRegularField: function(data, tabPointer, fieldArray, checkbox) { + var that = this; + var wrapperDiv = that._createElement("<div></div>").addClass("plate-setup-tab-default-field"); + var wrapperDivLeftSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"); + var wrapperDivRightSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-right-side "); + var nameContainer = that._createElement("<div></div>").addClass("plate-setup-tab-name").text(data.name); + var fieldContainer = that._createElement("<div></div>").addClass("plate-setup-tab-field-container"); - if (field.required) { - that.requiredField.push(field.id); - } + wrapperDivRightSide.append(nameContainer); + wrapperDivRightSide.append(fieldContainer); + wrapperDiv.append(wrapperDivLeftSide); + wrapperDiv.append(wrapperDivRightSide); + that.allDataTabs[tabPointer].append(wrapperDiv); - fieldArray.push(field); - that.fieldList.push(field); - that.fieldMap[field.id] = field; + var field = { + id: data.id, + name: data.name, + root: wrapperDiv, + data: data, + required: data.required + }; - // Adding checkbox - if (checkbox) { - that._addCheckBox(field); - } - that._createField(field); + if (field.required) { + that.requiredField.push(field.id); + } - field.onChange = function () { - var v = field.getValue(); - var data = {}; - data[field.id] = v; - that._addAllData(data); - }; - return field; + fieldArray.push(field); + that.fieldList.push(field); + that.fieldMap[field.id] = field; + + // Adding checkbox + if (checkbox) { + that._addCheckBox(field); + } + that._createField(field); + + field.onChange = function() { + var v = field.getValue(); + var data = {}; + data[field.id] = v; + that._addAllData(data); + }; + return field; }, - _makeMultiplexField: function (data, tabPointer, fieldArray) { + _makeMultiplexField: function(data, tabPointer, fieldArray) { var that = this; var wrapperDiv = that._createElement("<div></div>").addClass("plate-setup-tab-default-field"); var wrapperDivLeftSide = that._createElement("<div></div>").addClass("plate-setup-tab-field-left-side"); @@ -177,7 +178,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; //store required field if (field.required || requiredSubField.length) { - this.requiredField.push ({ + this.requiredField.push({ multiplexId: field.id, subFields: requiredSubField }); @@ -187,14 +188,14 @@ var plateLayOutWidget = plateLayOutWidget || {}; that._createField(field); that._addCheckBox(field); - subFieldList.forEach(function (subfield) { + subFieldList.forEach(function(subfield) { subfield.mainMultiplexField = field; fieldArray.push(subfield); that._createField(subfield); that._addCheckBox(subfield); delete that.defaultWell[subfield.id]; // overwrite subField setvalue - subfield.onChange = function () { + subfield.onChange = function() { var v = subfield.getValue(); var mainRefField = subfield.mainMultiplexField; var curId = mainRefField.singleSelectValue(); @@ -211,7 +212,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; field._changeMultiFieldValue(returnVal, null); var curDataLs = mainRefField.detailData; if (curDataLs !== null) { - curId = mainRefField.singleSelectValue(); + curId = mainRefField.singleSelectValue(); curDataLs = curDataLs.map(function(curData) { if (curData[mainRefField.id] === curId) { curData[subfield.id] = v; @@ -224,10 +225,10 @@ var plateLayOutWidget = plateLayOutWidget || {}; }); - field.getValue = function(){ + field.getValue = function() { var v = field.input.select2('data'); if (v.length) { - return v.map(function (i) { + return v.map(function(i) { return i.id; }); } diff --git a/src/js/add-warning-msg.js b/src/js/add-warning-msg.js index 963664b..c607f21 100644 --- a/src/js/add-warning-msg.js +++ b/src/js/add-warning-msg.js @@ -2,16 +2,16 @@ var plateLayOutWidget = plateLayOutWidget || {}; (function($, fabric) { - plateLayOutWidget.addWarningMsg = function () { + plateLayOutWidget.addWarningMsg = function() { // For those check boxes associated with every field in the tab return { - fieldWarningMsg: function (field, text, include) { + fieldWarningMsg: function(field, text, include) { var that = this; var imgId = "fieldWarning" + field.id; var img = $("<span>").html(that._assets.warningImg).attr("id", imgId).addClass("plate-field-warning-image"); //field.root.find(".plate-setup-tab-name").append('<img id="theImg" src="theImg.png" />') if (include) { - if (field.root.find("#" + imgId).length <= 0){ + if (field.root.find("#" + imgId).length <= 0) { field.root.find(".plate-setup-tab-name").text(" " + field.name); field.root.find(".plate-setup-tab-name").prepend(img); @@ -19,9 +19,9 @@ var plateLayOutWidget = plateLayOutWidget || {}; popText.text(text); field.root.find(".plate-setup-tab-name").append(popText); - $("#" + imgId).hover(function (e) { + $("#" + imgId).hover(function(e) { popText[0].style.display = 'flex'; - }, function () { + }, function() { popText.hide(); }); } @@ -35,7 +35,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; } }, - removeWarningMsg: function (field, text, include) { + removeWarningMsg: function(field, text, include) { var that = this; var imgId = "fieldWarning" + field.id; var img = $("<span>").html(that._assets.warningImg).attr("id", imgId).addClass("plate-field-warning-image"); @@ -47,9 +47,9 @@ var plateLayOutWidget = plateLayOutWidget || {}; popText.text(text); field.root.find(".plate-setup-tab-name").append(popText); - $("#" + imgId).hover(function (e) { + $("#" + imgId).hover(function(e) { popText[0].style.display = 'inline-block'; - }, function () { + }, function() { popText.hide(); }); @@ -67,11 +67,11 @@ var plateLayOutWidget = plateLayOutWidget || {}; var req = 0; var fill = 0; var fieldData = {}; - that.fieldList.forEach(function(field){ + that.fieldList.forEach(function(field) { fieldData[field.id] = []; }); - wells.forEach(function(well){ - if (!that.engine.wellEmpty(well)){ + wells.forEach(function(well) { + if (!that.engine.wellEmpty(well)) { for (var fieldId in fieldData) { if (fieldId in well) { fieldData[fieldId].push(well[fieldId]); @@ -83,12 +83,12 @@ var plateLayOutWidget = plateLayOutWidget || {}; }); for (var i = 0; i < that.fieldList.length; i++) { var field = that.fieldList[i]; - if (field.applyMultiplexSubFieldColor){ + if (field.applyMultiplexSubFieldColor) { field.applyMultiplexSubFieldColor(fieldData[field.id]); } else { if (field.required) { var include = false; - fieldData[field.id].forEach(function(val){ + fieldData[field.id].forEach(function(val) { // for multiselect if (val instanceof Array) { if (val.length === 0) { diff --git a/src/js/bottom-table.js b/src/js/bottom-table.js index c728ea6..bcbf12d 100755 --- a/src/js/bottom-table.js +++ b/src/js/bottom-table.js @@ -54,13 +54,13 @@ var plateLayOutWidget = plateLayOutWidget || {}; numberText.text(color); plateIdDiv.append(numberText); - numberText.click(function(evt){ - var addressToSelect = singleStack.map(function(addressIdx){ + numberText.click(function(evt) { + var addressToSelect = singleStack.map(function(addressIdx) { return that.indexToAddress(addressIdx) }); if (evt.ctrlKey) { - that.getSelectedAddress().forEach(function(val){ - if (addressToSelect.indexOf(val) < 0){ + that.getSelectedAddress().forEach(function(val) { + if (addressToSelect.indexOf(val) < 0) { addressToSelect.push(val); } }) @@ -146,7 +146,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; var dim = this.getDimensions(); var that = this; for (var colorIdx in colorLocIdxMap) { - colorLocMap[colorIdx] = colorLocIdxMap[colorIdx].map(function (locIdx) { + colorLocMap[colorIdx] = colorLocIdxMap[colorIdx].map(function(locIdx) { return that.indexToAddress(locIdx, dim); }) } diff --git a/src/js/canvas.js b/src/js/canvas.js index badb587..ea4a5d7 100755 --- a/src/js/canvas.js +++ b/src/js/canvas.js @@ -20,18 +20,18 @@ var plateLayOutWidget = plateLayOutWidget || {}; }, _initiateFabricCanvas: function() { - var w = this.canvasContainer.width(); - var h = this.canvasContainer.height(); + var w = this.canvasContainer.width(); + var h = this.canvasContainer.height(); this._setCanvasArea(w, h); this.mainFabricCanvas = new fabric.Canvas('DNAcanvas', { - backgroundColor: '#f5f5f5', - selection: false, - stateful: false, - hoverCursor: "pointer", - renderOnAddRemove: false, - }) + backgroundColor: '#f5f5f5', + selection: false, + stateful: false, + hoverCursor: "pointer", + renderOnAddRemove: false, + }) .setWidth(w) .setHeight(h); }, diff --git a/src/js/color-manager.js b/src/js/color-manager.js index 4568a11..24dc3a7 100755 --- a/src/js/color-manager.js +++ b/src/js/color-manager.js @@ -5,7 +5,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; plateLayOutWidget.colorManager = function() { return { - // See these are color pairs for the gradient. + // See these are color pairs for the gradient. colorPairs: [ ["#e6e6e6", "#808080"], ["#66e8ff", "#0082c8"], diff --git a/src/js/create-canvas-elements.js b/src/js/create-canvas-elements.js index f3bfa5a..afdf49d 100755 --- a/src/js/create-canvas-elements.js +++ b/src/js/create-canvas-elements.js @@ -6,31 +6,31 @@ var plateLayOutWidget = plateLayOutWidget || {}; // this class manages creating all the elements within canvas return { - scaleFactor: 1, + scaleFactor: 1, baseSizes: { - spacing: 48, - tile_radius: 22, - center_radius_complete: 10, - center_radius_incomplete: 14, - label_size: 14, - label_spacing: 24, + spacing: 48, + tile_radius: 22, + center_radius_complete: 10, + center_radius_incomplete: 14, + label_size: 14, + label_spacing: 24, text_size: 13, - stroke: 0.5, + stroke: 0.5, gap: 2 - }, + }, _setCanvasArea: function(w, h) { this.scaleFactor = Math.min( - h / (this.dimensions.rows * this.baseSizes.spacing + this.baseSizes.label_spacing), - w / (this.dimensions.cols * this.baseSizes.spacing + this.baseSizes.label_spacing)); + h / (this.dimensions.rows * this.baseSizes.spacing + this.baseSizes.label_spacing), + w / (this.dimensions.cols * this.baseSizes.spacing + this.baseSizes.label_spacing)); - var sizes = {} + var sizes = {}; for (var prop in this.baseSizes) { - sizes[prop] = this.baseSizes[prop] * this.scaleFactor; + sizes[prop] = this.baseSizes[prop] * this.scaleFactor; } - this.sizes = sizes; - }, + this.sizes = sizes; + }, _canvas: function() { // Those 1,2,3 s and A,B,C s @@ -46,12 +46,12 @@ var plateLayOutWidget = plateLayOutWidget || {}; var spacing = this.sizes.spacing; var d1 = this.sizes.label_spacing / 2; - var d2 = this.sizes.label_spacing + this.sizes.spacing / 2; - var fontSize = this.sizes.label_size; + var d2 = this.sizes.label_spacing + this.sizes.spacing / 2; + var fontSize = this.sizes.label_size; // For column - var top = d1; - var left = d2; + var top = d1; + var left = d2; for (var i = 1; i <= cols; i++) { var tempFabricText = new fabric.IText(i.toString(), { fill: 'black', @@ -64,16 +64,16 @@ var plateLayOutWidget = plateLayOutWidget || {}; selectable: false, fontWeight: "400" }); - left += spacing; + left += spacing; this.mainFabricCanvas.add(tempFabricText); } // for row - top = d2; - left = d1; + top = d2; + left = d1; for (var i = 1; i <= rows; i++) { - var tempFabricText = new fabric.IText(this.rowIndex[i-1], { + var tempFabricText = new fabric.IText(this.rowIndex[i - 1], { fill: 'black', originX: 'center', originY: 'center', @@ -84,7 +84,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; selectable: false, fontWeight: "400" }); - top += spacing; + top += spacing; this.mainFabricCanvas.add(tempFabricText); } @@ -97,9 +97,9 @@ var plateLayOutWidget = plateLayOutWidget || {}; var tileCounter = 0; for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { - var index = this.allTiles.length; - var tile = this._createTile(row, col); - tile.index = tileCounter++; + var index = this.allTiles.length; + var tile = this._createTile(row, col); + tile.index = tileCounter++; this.allTiles.push(tile); this.mainFabricCanvas.add(tile.background); this.mainFabricCanvas.add(tile.highlight); @@ -113,17 +113,17 @@ var plateLayOutWidget = plateLayOutWidget || {}; this._fabricEvents(); }, - _createTile: function (row, col) { - var tile = {}; + _createTile: function(row, col) { + var tile = {}; - tile.visible = false; - tile.colorIndex = null; - tile.row = row; - tile.col = col; - tile.address = this.rowIndex[row] + (col + 1); + tile.visible = false; + tile.colorIndex = null; + tile.row = row; + tile.col = col; + tile.address = this.rowIndex[row] + (col + 1); var top = (row + 1) * this.sizes.spacing; - var left = (col + 1) * this.sizes.spacing; + var left = (col + 1) * this.sizes.spacing; tile.background = new fabric.Circle({ top: top, @@ -140,8 +140,8 @@ var plateLayOutWidget = plateLayOutWidget || {}; tile.background.setGradient("fill", { type: "radial", - x1: this.sizes.tile_radius, - x2: this.sizes.tile_radius, + x1: this.sizes.tile_radius, + x2: this.sizes.tile_radius, y1: this.sizes.tile_radius + this.sizes.gap, y2: this.sizes.tile_radius + this.sizes.gap, r1: this.sizes.tile_radius - this.sizes.gap, @@ -172,7 +172,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; radius: this.sizes.tile_radius, stroke: 'gray', strokeWidth: this.sizes.stroke, - evented: false, + evented: false, visible: false }); @@ -203,10 +203,10 @@ var plateLayOutWidget = plateLayOutWidget || {}; visible: false }); - return tile; - }, + return tile; + }, - setTileComplete: function (tile, complete) { + setTileComplete: function(tile, complete) { if (complete) { tile.circleCenter.radius = this.sizes.center_radius_complete; tile.circleText.fill = "black"; @@ -216,22 +216,22 @@ var plateLayOutWidget = plateLayOutWidget || {}; tile.circleText.fill = "red"; tile.circleText.fontWeight = 'bold'; } - }, + }, - setTileVisible: function (tile, visible) { + setTileVisible: function(tile, visible) { tile.visible = visible; tile.circle.visible = tile.visible; tile.circleCenter.visible = tile.visible; tile.circleText.visible = tile.visible; }, - setTileColor: function(tile, color, stackPointer) { + setTileColor: function(tile, color) { this.setTileVisible(tile, true); - tile.colorIndex = parseInt(color); + tile.colorIndex = parseInt(color); tile.circleText.text = String(tile.colorIndex); if (color > 0) { - color = ((color - 1) % (this.colorPairs.length -1)) + 1; + color = ((color - 1) % (this.colorPairs.length - 1)) + 1; } var colorStops = this.colorPairs[color]; diff --git a/src/js/create-field.js b/src/js/create-field.js index 2792cb7..249cc8f 100755 --- a/src/js/create-field.js +++ b/src/js/create-field.js @@ -273,15 +273,14 @@ var plateLayOutWidget = plateLayOutWidget || {}; return ""; }; - field.multiOnChange = function (added, removed) { + field.multiOnChange = function(added, removed) { if (added) { added = added.id.toString(); } if (removed) { removed = removed.id.toString(); } - var data = { - }; + var data = {}; data[field.id] = { multi: true, added: added, @@ -291,7 +290,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; that._addAllData(data); }; - field.parseText = function(value){ + field.parseText = function(value) { var v = value; if (v && v.length) { v = v.map(function(opt) { @@ -559,7 +558,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; // val now contains unit field.getText = function(val) { - if (typeof(val) === 'object' && val) { + if (typeof (val) === 'object' && val) { var v = val.value; var u = val.unit; if (v == null) { @@ -586,9 +585,9 @@ var plateLayOutWidget = plateLayOutWidget || {}; return v; }; - field.parseText = function(v){ + field.parseText = function(v) { var textVal = field.parseValue(v); - if (textVal && typeof(textVal) === "object"){ + if (textVal && typeof (textVal) === "object") { return textVal.value + textVal.unit; } else if (textVal) { return textVal @@ -726,7 +725,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; field.singleSelect.appendTo(fieldContainer1); - field.singleSelectValue = function () { + field.singleSelectValue = function() { var v = field.singleSelect.select2("data"); if (v != null) { v = v.id; @@ -734,7 +733,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; return v; }; - var setSingleSelectOptions = function (v, selected_v) { + var setSingleSelectOptions = function(v, selected_v) { var opts = { allowClear: false, placeholder: "select", @@ -754,7 +753,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; field.singleSelect.prop("disabled", opts.data.length == 0); }; - var singleSelectChange = function () { + var singleSelectChange = function() { var v = field.singleSelectValue(); field.updateSubFieldUnitOpts(v); @@ -808,7 +807,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; } if (removed) { - if (removed.value){ + if (removed.value) { val = removed.value; } else { newSubFieldValue[field.id] = removed.id; @@ -891,7 +890,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; field.subFieldList.forEach(function(subField) { if (subField.data.hasMultiplexUnit) { if (curOpts && curOpts.hasOwnProperty("unitOptions")) { - subField.setUnitOpts(curOpts.unitOptions[subField.id]); + subField.setUnitOpts(curOpts.unitOptions[subField.id]); } else { subField.setUnitOpts(null); } @@ -945,7 +944,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; }); } else { if (subfield.data.units) { - if (subfield.data.units.length > 1){ + if (subfield.data.units.length > 1) { subfield.disabled(false); } } @@ -955,8 +954,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; }; newVal[subfield.id] = subfield.parseValue(val); } - } - else { + } else { newVal[subfield.id] = subfield.parseValue(null); } }); @@ -1040,7 +1038,8 @@ var plateLayOutWidget = plateLayOutWidget || {}; var valCount = 0; var completionPct = 0; var include = false; - function getSubfieldStatus (vals) { + + function getSubfieldStatus(vals) { var req = 0; var fill = 0; for (var subFieldId in field.subFieldList) { @@ -1049,7 +1048,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; if (subField.required) { include = true; req++; - if (typeof(curVal) === 'object' && curVal) { + if (typeof curVal === 'object' && curVal) { if (curVal.value) { fill++; } @@ -1058,12 +1057,12 @@ var plateLayOutWidget = plateLayOutWidget || {}; } } } - return fill/req; + return fill / req; } // for cases has value in multiplex field if (valList) { - if (valList.length > 0){ + if (valList.length > 0) { for (var idx in valList) { valCount++; var vals = valList[idx]; @@ -1073,37 +1072,37 @@ var plateLayOutWidget = plateLayOutWidget || {}; include = true; valCount = 1; } - } else if (field.required) { + } else if (field.required) { include = true; valCount = 1; } return { include: include, - completionPct: completionPct/valCount + completionPct: completionPct / valCount }; }; // valList contains all of the vals for selected val - field.applyMultiplexSubFieldColor = function(valList){ - function updateSubFieldWarningMap (vals) { + field.applyMultiplexSubFieldColor = function(valList) { + function updateSubFieldWarningMap(vals) { for (var subFieldId in field.subFieldList) { var subField = field.subFieldList[subFieldId]; // loop through each well's multiplexval list - if (vals === null){ - if (field.required && subField.required){ + if (vals === null) { + if (field.required && subField.required) { subFieldWarningMap[subField.id].warningStatus.push(true); } - } else if (typeof(vals) === "object") { + } else if (typeof (vals) === "object") { if (vals.length === 0) { - if (field.required && subField.required){ + if (field.required && subField.required) { subFieldWarningMap[subField.id].warningStatus.push(true); } } else { for (var multiplexIdx in vals) { var curVal = vals[multiplexIdx][subField.id]; if (subField.required) { - if (typeof(curVal) === 'object' && curVal) { + if (typeof (curVal) === 'object' && curVal) { if (!curVal.value) { subFieldWarningMap[subField.id].warningStatus.push(true); } else { @@ -1122,7 +1121,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; } var subFieldWarningMap = {}; - field.subFieldList.forEach(function(subField){ + field.subFieldList.forEach(function(subField) { if (subField.required) { subFieldWarningMap[subField.id] = { field: subField, @@ -1138,11 +1137,11 @@ var plateLayOutWidget = plateLayOutWidget || {}; var requiredSubField = []; var mainFieldStatus = []; - for (var subFieldId in subFieldWarningMap){ + for (var subFieldId in subFieldWarningMap) { var subField = subFieldWarningMap[subFieldId].field; if (subFieldWarningMap[subFieldId].warningStatus.indexOf(true) >= 0) { - var text = subField.name + " is a required subfield for " + field.name + ", please make sure all " + field.name + " have " + subField.name; - if (field.required){ + var text = subField.name + " is a required subfield for " + field.name + ", please make sure all " + field.name + " have " + subField.name; + if (field.required) { that.fieldWarningMsg(subField, text, true); mainFieldStatus.push(true); } else { @@ -1171,16 +1170,16 @@ var plateLayOutWidget = plateLayOutWidget || {}; field.parseMainFieldVal = function(val) { var optMap = field.data.options; - for (var idx = 0; idx < optMap.length; idx++){ + for (var idx = 0; idx < optMap.length; idx++) { var curOpt = optMap[idx]; - if (curOpt.id === val){ + if (curOpt.id === val) { return curOpt.text } } }; }, - _deleteDialog: function (field) { + _deleteDialog: function(field) { var that = this; var valMap = field.allSelectedMultipleVal; @@ -1204,7 +1203,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; var tableArea = $("<div/>").appendTo(dialogContent); var buttonRow = $("<div/>").addClass("dialog-buttons").css("justify-content", "flex-end").appendTo(dialogContent); - if (valToRemove.length > 0){ + if (valToRemove.length > 0) { // apply CSS property for table $("<p/>").text(field.name + " in selected wells: choose items to delete and click the delete button below").appendTo(tableArea); @@ -1218,7 +1217,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; var deleteCheckedButton = $("<button class='multiple-field-manage-delete-button'>Delete Checked Items</button>"); buttonRow.append(deleteCheckedButton); deleteCheckedButton.click(function() { - table.find("input:checked").each(function () { + table.find("input:checked").each(function() { var val = this.value; field.multiOnChange(null, {id: val}); }); @@ -1245,7 +1244,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; } }, - _deleteDialogTable: function (field, valMap) { + _deleteDialogTable: function(field, valMap) { var that = this; var colName = [field.name, "Counts"]; //Added because it was missing... no idea what the original should have been if (!that.readOnly) { @@ -1255,13 +1254,13 @@ var plateLayOutWidget = plateLayOutWidget || {}; var thead = $('<thead/>').appendTo(table); var tr = $('<tr/>').appendTo(thead); - tr.append(colName.map(function (text) { + tr.append(colName.map(function(text) { return $('<th/>').text(text); })); var tbody = $("<tbody/>").appendTo(table); - field.data.options.forEach(function (opt) { + field.data.options.forEach(function(opt) { if (opt.id in valMap) { var tr = $('<tr/>').appendTo(tbody); var checkbox = $("<input type='checkbox'>").prop("value", opt.id); @@ -1276,7 +1275,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; return table; }, - _createDeleteButton: function (field) { + _createDeleteButton: function(field) { var that = this; var deleteButton = $("<button/>").addClass("plate-setup-remove-all-button"); deleteButton.id = field.id + "Delete"; @@ -1287,7 +1286,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; field.deleteButton = deleteButton; field.root.find(".plate-setup-tab-field-right-side").append(buttonContainer); - deleteButton.click(function () { + deleteButton.click(function() { that._deleteDialog(field); }); } diff --git a/src/js/engine.js b/src/js/engine.js index 35316cd..d0694f4 100755 --- a/src/js/engine.js +++ b/src/js/engine.js @@ -14,7 +14,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; stackUpWithColor: {}, stackPointer: 2, - wellEmpty: function (well) { + wellEmpty: function(well) { for (var prop in well) { var curVal = well[prop]; if (curVal !== null && curVal !== undefined) { @@ -39,16 +39,16 @@ var plateLayOutWidget = plateLayOutWidget || {}; var data = this.derivative[idx]; var wellData = {}; for (var i = 0; i < THIS.globalSelectedAttributes.length; i++) { - var attr = THIS.globalSelectedAttributes[i]; + var attr = THIS.globalSelectedAttributes[i]; - if (attr in THIS.globalSelectedMultiplexSubfield){ + if (attr in THIS.globalSelectedMultiplexSubfield) { var selectedSubFields = THIS.globalSelectedMultiplexSubfield[attr]; var newMultiplexVal = []; - for (var multiplexIdx in data[attr]){ + for (var multiplexIdx in data[attr]) { var curMultiplexVals = data[attr][multiplexIdx]; var newVal = {}; newVal[attr] = curMultiplexVals[attr]; - selectedSubFields.forEach(function (subFieldId) { + selectedSubFields.forEach(function(subFieldId) { newVal[subFieldId] = curMultiplexVals[subFieldId]; }); newMultiplexVal.push(newVal); @@ -61,15 +61,19 @@ var plateLayOutWidget = plateLayOutWidget || {}; } } if ($.isEmptyObject(wellData)) { - derivativeJson[idx] = null; + derivativeJson[idx] = null; } else { derivativeJson[idx] = JSON.stringify(wellData); } } while (!$.isEmptyObject(derivativeJson)) { - var keys = Object.keys(derivativeJson).map(function (k) {return parseFloat(k, 10);}); - keys.sort(function (a, b) {return a-b;}); + var keys = Object.keys(derivativeJson).map(function(k) { + return parseFloat(k, 10); + }); + keys.sort(function(a, b) { + return a - b; + }); var refDerivativeIndex = keys[0]; var referenceDerivative = derivativeJson[refDerivativeIndex]; @@ -87,7 +91,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; } else { // if checked boxes have values for (var i = 0; i < keys.length; i++) { - var idx = keys[i]; + var idx = keys[i]; if (referenceDerivative == derivativeJson[idx]) { arr.push(idx); this.stackUpWithColor[this.stackPointer] = arr; @@ -119,14 +123,14 @@ var plateLayOutWidget = plateLayOutWidget || {}; for (var tileIndex in arr) { wholeNoTiles++; - var index = this.stackUpWithColor[color][tileIndex]; + var index = this.stackUpWithColor[color][tileIndex]; var tile = THIS.allTiles[index]; var well = this.derivative[index]; this.colorMap.set(index, color); THIS.setTileColor(tile, color); // Checks if all the required fields are filled var completion = this.checkCompletion(well, tile); - THIS.setTileComplete(tile, completion == 1); + THIS.setTileComplete(tile, completion == 1); wholePercentage = wholePercentage + completion; } } @@ -142,11 +146,11 @@ var plateLayOutWidget = plateLayOutWidget || {}; }, checkCompletion: function(wellData, tile) { - var req = 0; + var req = 0; var fill = 0; for (var i = 0; i < THIS.fieldList.length; i++) { var field = THIS.fieldList[i]; - if (field.checkMultiplexCompletion){ + if (field.checkMultiplexCompletion) { // also apply color var multiplexStatus = field.checkMultiplexCompletion(wellData[field.id]); if (multiplexStatus.include) { @@ -163,7 +167,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; } } if (req === fill) { - return 1; + return 1; } return fill / req; }, diff --git a/src/js/example.js b/src/js/example.js index 4080092..fbf4af7 100644 --- a/src/js/example.js +++ b/src/js/example.js @@ -1,210 +1,212 @@ // Wait for all the script load from the loader.js and fire up -window.onload = function () { - var fields = { - polymerase: { - required: true, - id: 'pol', - name: 'Polymerase', - type: 'multiselect', - placeHolder: "Polymerase", - options: [ - { - id: 234, - text: 'Taq 1, processive enzyme with long name' - }, - { - id: 123, - text: 'Taq 2' - }, - { - id: 3, - text: 'Taq 3' - }, - { - id: 4, - text: 'Taq 4' - }, - { - id: 5, - text: 'Taq 5' - } - ] +window.onload = function() { + var fields = { + polymerase: { + required: true, + id: 'pol', + name: 'Polymerase', + type: 'multiselect', + placeHolder: "Polymerase", + options: [ + { + id: 234, + text: 'Taq 1, processive enzyme with long name' }, - volume: { - required: true, - id: 'volume', - name: 'Volume', - type: 'numeric', - placeholder: "Volume", - units: ["uL", "mL"], - defaultUnit: "uL" + { + id: 123, + text: 'Taq 2' }, - conc: { - required: true, - id: 'conc', - name: 'Concentration', - type: 'numeric', - placeholder: "Conc.", - defaultUnit: "ng/ul (final)" + { + id: 3, + text: 'Taq 3' }, - on_ice: { - required: true, - id: "on_ice", - name: "On Ice", - type: "boolean", - placeHolder: "On Ice" - } - }; - var amplicons_field = { - amplicons: { - required: true, - id: 'amplicons', - name: "Amplicons", - type: "multiplex", - placeHolder: "Amplicons", - options: [ - { - id: 'A', - text: 'Amplicon_A' - }, - { - id: 'B', - text: 'Amplicon_B' - }, - { - id: 'C', - text: 'Amplicon_C' - }, - { - id: 'D', - text: 'Amplicon_D' - } - ], - multiplexFields: { - template_ngul: { - required: true, - id: 'template_ngul', - name: 'template conc', - type: 'select', - options: [ - {id: 'a', text: "a"}, - {id: 'b', text: "b"}, - {id: 'c', text: "c"} - ] - }, - primer_umolarity: { - required: true, - id: 'primer_umolarity', - name: 'Primer conc', - type: 'numeric', - placeHolder: "Primer", - units: ['uM (final)', "unit1"], - defaultUnit: 'uM (final)' - }, - probe_umolarity: { - required: true, - id: 'probe_umolarity', - name: 'Probe conc', - type: 'numeric', - placeHolder: "Probe", - defaultUnit: 'uM (final)' - }, - dilution_factor: { - required: true, - id: 'dilution_factor', - name: 'Dilution factor', - type: 'numeric', - placeHolder: "Dilution factor", - defaultUnit: 'X' - } - }, + { + id: 4, + text: 'Taq 4' }, - }; - var attributes = { - presets: [ - { - title: "Pol/Vol", - fields: ["volume", "pol"] - }, - { - title: "Vol", - fields: ["volume"] - } - ], - tabs: [ - { - name: "Settings", - fields: fields - }, - { - name: "amplicons", - fields: amplicons_field - } - ] - }; - window.plateData = {}; - function makeNewPlate(obj) { - var d = $("#my-plate-layout").plateLayOut("getDimensions"); - var rows = d.rows; - var cols = d.cols; - var wells = {}; - for (var r = 0; r < rows; r++) { - var volume = 100; - var pol = (r < (rows / 2)) ? 234 : 123; - var on_ice = Boolean(r % 2); - for (var c = 0; c < cols; c++) { - var i = r * cols + c; - var v = volume; - var vunit = "mL"; - var amplicons = [{ - amplicons: "A", - template_ngul: 'a', - primer_umolarity: 2, - probe_umolarity: 3, - dilution_factor: 4 - }, - { - amplicons: "B", - template_ngul: 'b', - primer_umolarity: 22, - probe_umolarity: 33, - dilution_factor: 44 - }]; - if (v < 1) { - v *= 1000; - vunit = "uL"; - } - wells[i.toString()] = { - volume: v, - pol: pol, - amplicons: amplicons, - on_ice: on_ice - }; - if ((c % 2) > 0) { - volume /= 10 - } - } + { + id: 5, + text: 'Taq 5' } - return { - derivative: wells, - checkboxes: ["volume", "pol"] - }; + ] + }, + volume: { + required: true, + id: 'volume', + name: 'Volume', + type: 'numeric', + placeholder: "Volume", + units: ["uL", "mL"], + defaultUnit: "uL" + }, + conc: { + required: true, + id: 'conc', + name: 'Concentration', + type: 'numeric', + placeholder: "Conc.", + defaultUnit: "ng/ul (final)" + }, + on_ice: { + required: true, + id: "on_ice", + name: "On Ice", + type: "boolean", + placeHolder: "On Ice" } - $("#my-plate-layout").plateLayOut({ - numRows: 8, - numCols: 12, - attributes: attributes, - // scrollToGroup: false, // optional + }; + var amplicons_field = { + amplicons: { + required: true, + id: 'amplicons', + name: "Amplicons", + type: "multiplex", + placeHolder: "Amplicons", + options: [ + { + id: 'A', + text: 'Amplicon_A' + }, + { + id: 'B', + text: 'Amplicon_B' + }, + { + id: 'C', + text: 'Amplicon_C' + }, + { + id: 'D', + text: 'Amplicon_D' + } + ], + multiplexFields: { + template_ngul: { + required: true, + id: 'template_ngul', + name: 'template conc', + type: 'select', + options: [ + {id: 'a', text: "a"}, + {id: 'b', text: "b"}, + {id: 'c', text: "c"} + ] + }, + primer_umolarity: { + required: true, + id: 'primer_umolarity', + name: 'Primer conc', + type: 'numeric', + placeHolder: "Primer", + units: ['uM (final)', "unit1"], + defaultUnit: 'uM (final)' + }, + probe_umolarity: { + required: true, + id: 'probe_umolarity', + name: 'Probe conc', + type: 'numeric', + placeHolder: "Probe", + defaultUnit: 'uM (final)' + }, + dilution_factor: { + required: true, + id: 'dilution_factor', + name: 'Dilution factor', + type: 'numeric', + placeHolder: "Dilution factor", + defaultUnit: 'X' + } + }, + }, + }; + var attributes = { + presets: [ + { + title: "Pol/Vol", + fields: ["volume", "pol"] + }, + { + title: "Vol", + fields: ["volume"] + } + ], + tabs: [ + { + name: "Settings", + fields: fields + }, + { + name: "amplicons", + fields: amplicons_field + } + ] + }; + window.plateData = {}; - updateWells: function (event, data) { - //data has changed - window.plateData = data; - console.log(Object.keys(data.derivative).length + " wells updated"); + function makeNewPlate(obj) { + var d = $("#my-plate-layout").plateLayOut("getDimensions"); + var rows = d.rows; + var cols = d.cols; + var wells = {}; + for (var r = 0; r < rows; r++) { + var volume = 100; + var pol = (r < (rows / 2)) ? 234 : 123; + var on_ice = Boolean(r % 2); + for (var c = 0; c < cols; c++) { + var i = r * cols + c; + var v = volume; + var vunit = "mL"; + var amplicons = [{ + amplicons: "A", + template_ngul: 'a', + primer_umolarity: 2, + probe_umolarity: 3, + dilution_factor: 4 }, - created: function (event, data) { - console.log("Created"); + { + amplicons: "B", + template_ngul: 'b', + primer_umolarity: 22, + probe_umolarity: 33, + dilution_factor: 44 + }]; + if (v < 1) { + v *= 1000; + vunit = "uL"; + } + wells[i.toString()] = { + volume: v, + pol: pol, + amplicons: amplicons, + on_ice: on_ice + }; + if ((c % 2) > 0) { + volume /= 10 } - }); - window.plateData = makeNewPlate(); - $("#my-plate-layout").plateLayOut("getPlates", window.plateData); + } + } + return { + derivative: wells, + checkboxes: ["volume", "pol"] + }; + } + + $("#my-plate-layout").plateLayOut({ + numRows: 8, + numCols: 12, + attributes: attributes, + // scrollToGroup: false, // optional + + updateWells: function(event, data) { + //data has changed + window.plateData = data; + console.log(Object.keys(data.derivative).length + " wells updated"); + }, + created: function(event, data) { + console.log("Created"); + } + }); + window.plateData = makeNewPlate(); + $("#my-plate-layout").plateLayOut("getPlates", window.plateData); }; \ No newline at end of file diff --git a/src/js/fabric-events.js b/src/js/fabric-events.js index 589b2fa..3097085 100755 --- a/src/js/fabric-events.js +++ b/src/js/fabric-events.js @@ -105,7 +105,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; that.decideSelectedFields(); that.mainFabricCanvas.renderAll(); that._trigger("selectedWells", null, {selectedAddress: that.getSelectedAddress()}); - if(that.options.scrollToGroup === undefined || that.options.scrollToGroup) { + if (that.options.scrollToGroup === undefined || that.options.scrollToGroup) { that.selectObjectInBottomTab(); } }); @@ -128,7 +128,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; r: well.row, c: well.col }); - if (this.addressAllowToEdit.indexOf(address) < 0) { + if (this.addressAllowToEdit.indexOf(address) < 0) { flag = false; this.setFieldsDisabled(true); } else { @@ -178,18 +178,18 @@ var plateLayOutWidget = plateLayOutWidget || {}; }) }, - _getSelectedWells: function () { - var that = this; - return this.allSelectedObjects.map(function (tile) { + _getSelectedWells: function() { + var that = this; + return this.allSelectedObjects.map(function(tile) { var well = that.engine.derivative[tile.index]; if (!well) { - well = that.defaultWell; + well = that.defaultWell; } - return well; - }); + return well; + }); }, - _getCommonFields: function (wells) { + _getCommonFields: function(wells) { if (wells.length) { var referenceWell = wells[0]; var referenceFields = $.extend(true, {}, referenceWell); @@ -197,11 +197,11 @@ var plateLayOutWidget = plateLayOutWidget || {}; var fields = wells[i]; for (var field in referenceFields) { if (Array.isArray(referenceFields[field])) { - var refArr = referenceFields[field]; - var agrArr = []; + var refArr = referenceFields[field]; + var agrArr = []; for (var j = 0; j < refArr.length; j++) { var v = refArr[j]; - if (v && typeof(v) === "object") { + if (v && typeof (v) === "object") { if (this.containsObject(v, fields[field])) { agrArr.push(v); } @@ -211,10 +211,10 @@ var plateLayOutWidget = plateLayOutWidget || {}; } } } - referenceFields[field] = agrArr; + referenceFields[field] = agrArr; } else { - if (fields[field] && typeof(fields[field]) ==="object" && referenceFields[field] && typeof(referenceFields[field]) ==="object"){ - if ((fields[field].value !== referenceFields[field].value) || (fields[field].unit !== referenceFields[field].unit)){ + if (fields[field] && typeof (fields[field]) === "object" && referenceFields[field] && typeof (referenceFields[field]) === "object") { + if ((fields[field].value !== referenceFields[field].value) || (fields[field].unit !== referenceFields[field].unit)) { delete referenceFields[field]; } } else if (referenceFields[field] != fields[field]) { @@ -235,11 +235,11 @@ var plateLayOutWidget = plateLayOutWidget || {}; list.forEach(function(val) { //evaluate val and obj var evaluate = []; - Object.keys(val).forEach(function(listKey){ - if (Object.keys(obj).indexOf(listKey) >= 0){ + Object.keys(val).forEach(function(listKey) { + if (Object.keys(obj).indexOf(listKey) >= 0) { var curVal = val[listKey]; - if (typeof(curVal) === 'object' && curVal) { - if (obj[listKey]){ + if (typeof (curVal) === 'object' && curVal) { + if (obj[listKey]) { evaluate.push((curVal.unit === obj[listKey].unit) && (curVal.value === obj[listKey].value)); } else { // when obj[listKey] is null but curVal is not @@ -258,7 +258,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; } }, - _getCommonWell: function (wells) { + _getCommonWell: function(wells) { if (wells.length) { var referenceWell = wells[0]; var referenceFields = $.extend(true, {}, referenceWell); @@ -267,12 +267,12 @@ var plateLayOutWidget = plateLayOutWidget || {}; var fields = well; for (var field in referenceFields) { if (Array.isArray(referenceFields[field])) { - var refArr = referenceFields[field]; - var agrArr = []; + var refArr = referenceFields[field]; + var agrArr = []; for (var j = 0; j < refArr.length; j++) { var v = refArr[j]; // for multiplex field - if (typeof(refArr[j]) ==="object"){ + if (typeof (refArr[j]) === "object") { if (this.containsObject(v, fields[field])) { agrArr.push(v); } @@ -282,10 +282,10 @@ var plateLayOutWidget = plateLayOutWidget || {}; } } } - referenceFields[field] = agrArr; + referenceFields[field] = agrArr; } else { - if (fields[field] && typeof(fields[field]) ==="object" && referenceFields[field] && typeof(referenceFields[field]) ==="object"){ - if ((fields[field].value !== referenceFields[field].value) || (fields[field].unit !== referenceFields[field].unit)){ + if (fields[field] && typeof (fields[field]) === "object" && referenceFields[field] && typeof (referenceFields[field]) === "object") { + if ((fields[field].value !== referenceFields[field].value) || (fields[field].unit !== referenceFields[field].unit)) { referenceFields[field] = null; } } else if (referenceFields[field] != fields[field]) { @@ -297,30 +297,30 @@ var plateLayOutWidget = plateLayOutWidget || {}; } return referenceFields; } else { - return this.defaultWell; + return this.defaultWell; } - }, + }, - _getAllMultipleVal: function (wells) { + _getAllMultipleVal: function(wells) { var multipleFieldList = this.multipleFieldList; multipleFieldList.forEach(function(multiplexField) { - if(wells.length) { + if (wells.length) { var curMultipleVal = {}; - wells.forEach(function (wellData) { + wells.forEach(function(wellData) { var id = multiplexField.id; - if (wellData[id]){ + if (wellData[id]) { if (wellData[id].length > 0) { - wellData[id].forEach(function (multipleVal) { - if (typeof(multipleVal) === 'object') { + wellData[id].forEach(function(multipleVal) { + if (typeof (multipleVal) === 'object') { if (multipleVal[id] in curMultipleVal) { - curMultipleVal[multipleVal[id]] ++; + curMultipleVal[multipleVal[id]]++; } else { curMultipleVal[multipleVal[id]] = 1; } } else { if (multipleVal in curMultipleVal) { - curMultipleVal[multipleVal] ++; + curMultipleVal[multipleVal]++; } else { curMultipleVal[multipleVal] = 1; @@ -341,24 +341,24 @@ var plateLayOutWidget = plateLayOutWidget || {}; var wells = this._getSelectedWells(); this._getAllMultipleVal(wells); this.applyFieldWarning(wells); - var well = this._getCommonWell(wells); + var well = this._getCommonWell(wells); this._addDataToTabFields(well); }, // get well value differences for each well in wellsHash getDifferentWellsVals: function(wellsHash) { var wells = []; - for (var wellId in wellsHash){ + for (var wellId in wellsHash) { wells.push(wellsHash[wellId]); } var differentWellsVals = {}; - if (wells.length > 1){ + if (wells.length > 1) { var commonWell = this._getCommonWell(wells); var allFieldVal = {}; for (var fieldIdx in wellsHash[0]) { allFieldVal[fieldIdx] = []; } - for (var wellIdx in wells){ + for (var wellIdx in wells) { var diffWellVal = {}; var curWellData = wells[wellIdx]; for (var fieldId in curWellData) { @@ -368,10 +368,10 @@ var plateLayOutWidget = plateLayOutWidget || {}; if (Array.isArray(curVal)) { // get uncommonVal newVal = []; - for (var idx = 0; idx < curVal.length; idx ++){ + for (var idx = 0; idx < curVal.length; idx++) { var curMultiVal = curVal[idx]; // multiplex field - if (curMultiVal && typeof(curMultiVal === "object")){ + if (curMultiVal && typeof (curMultiVal === "object")) { if (!this.containsObject(curMultiVal, commonVal)) { newVal.push(curMultiVal); if (!this.containsObject(curMultiVal, allFieldVal[fieldId])) { @@ -387,9 +387,9 @@ var plateLayOutWidget = plateLayOutWidget || {}; } } } - } else if (curVal && typeof(curVal) === "object"){ - if (commonVal && typeof(commonVal) ==="object"){ - if (!((curVal.value === commonVal.value) || (curVal.unit === commonVal.unit))){ + } else if (curVal && typeof (curVal) === "object") { + if (commonVal && typeof (commonVal) === "object") { + if (!((curVal.value === commonVal.value) || (curVal.unit === commonVal.unit))) { newVal = curVal; if (!this.containsObject(curVal, allFieldVal[fieldId])) { allFieldVal[fieldId].push(curVal); @@ -417,7 +417,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; // clean up step for fields that are empty for (var fieldId in allFieldVal) { if (allFieldVal[fieldId].length === 0) { - for (var wellIdx in differentWellsVals){ + for (var wellIdx in differentWellsVals) { delete differentWellsVals[wellIdx][fieldId]; } } @@ -428,11 +428,11 @@ var plateLayOutWidget = plateLayOutWidget || {}; var well = {}; for (var fieldId in wellsHash[0]) { var curVal = wellsHash[0][fieldId]; - if (Array.isArray(curVal)){ + if (Array.isArray(curVal)) { if (curVal.length > 0) { well[fieldId] = curVal } - } else if (curVal){ + } else if (curVal) { well[fieldId] = curVal; } } @@ -443,10 +443,10 @@ var plateLayOutWidget = plateLayOutWidget || {}; }, // get all wells that has data - getWellSetAddressWithData: function(){ + getWellSetAddressWithData: function() { var address = []; var derivative = this.engine.derivative; - for (var id in derivative){ + for (var id in derivative) { address.push(this.indexToAddress(id)); } return address; diff --git a/src/js/image_assets.js b/src/js/image_assets.js index 1310a8a..1f8ca0e 100644 --- a/src/js/image_assets.js +++ b/src/js/image_assets.js @@ -1,11 +1,11 @@ var plateLayOutWidget = plateLayOutWidget || {}; -plateLayOutWidget.assets = function () { - return { - _assets: { - doImg: '✓', - dontImg: '', - warningImg: '⚠' - } - }; +plateLayOutWidget.assets = function() { + return { + _assets: { + doImg: '✓', + dontImg: '', + warningImg: '⚠' + } + }; }; diff --git a/src/js/interface.js b/src/js/interface.js index ed5aa9e..ef68e70 100755 --- a/src/js/interface.js +++ b/src/js/interface.js @@ -57,22 +57,22 @@ var plateLayOutWidget = plateLayOutWidget || {}; return $(element); }, - _setShortcuts: function () { - var that = this; - window.addEventListener("cut", function (e) { + _setShortcuts: function() { + var that = this; + window.addEventListener("cut", function(e) { if (document.activeElement == document.body) { that.copyCriteria(); that.clearCriteria(); e.preventDefault(); } }); - window.addEventListener("copy", function (e) { + window.addEventListener("copy", function(e) { if (document.activeElement == document.body) { that.copyCriteria(); e.preventDefault(); } }); - window.addEventListener("paste", function (e) { + window.addEventListener("paste", function(e) { if (document.activeElement == document.body) { that.pasteCriteria(); e.preventDefault(); diff --git a/src/js/load-plate.js b/src/js/load-plate.js index 7bd1b3a..9111b6b 100755 --- a/src/js/load-plate.js +++ b/src/js/load-plate.js @@ -7,29 +7,29 @@ var plateLayOutWidget = plateLayOutWidget || {}; // Remember THIS points to plateLayOutWidget and 'this' points to engine return { - getPlates: function (data) { + getPlates: function(data) { //sanitize input - var derivative = {}; + var derivative = {}; for (var index in data.derivative) { - var well = data.derivative[index]; - derivative[index] = this.sanitizeWell(well); + var well = data.derivative[index]; + derivative[index] = this.sanitizeWell(well); } - var checkboxes = data.checkboxes || []; - var selection = this.sanitizeAreas(data.selectedAreas, data.focalWell); + var checkboxes = data.checkboxes || []; + var selection = this.sanitizeAreas(data.selectedAreas, data.focalWell); var sanitized = { "derivative": derivative, "checkboxes": checkboxes, "selectedAreas": selection.selectedAreas, "focalWell": selection.focalWell - }; + }; this.setData(sanitized); - }, + }, - sanitizeAreas: function (selectedAreas, focalWell) { - var that = this; + sanitizeAreas: function(selectedAreas, focalWell) { + var that = this; var rows = this.dimensions.rows; var cols = this.dimensions.cols; @@ -37,14 +37,14 @@ var plateLayOutWidget = plateLayOutWidget || {}; selectedAreas = []; } if (selectedAreas.length) { - selectedAreas = selectedAreas.map(function (area) { + selectedAreas = selectedAreas.map(function(area) { return { - minCol: that._coordIndex(Math.min(area.minCol, area.maxCol), cols), - minRow: that._coordIndex(Math.min(area.minRow, area.maxRow), rows), - maxCol: that._coordIndex(Math.max(area.minCol, area.maxCol), cols), + minCol: that._coordIndex(Math.min(area.minCol, area.maxCol), cols), + minRow: that._coordIndex(Math.min(area.minRow, area.maxRow), rows), + maxCol: that._coordIndex(Math.max(area.minCol, area.maxCol), cols), maxRow: that._coordIndex(Math.max(area.minRow, area.maxRow), rows) - }; - }); + }; + }); var area = selectedAreas[selectedAreas.length - 1]; if (focalWell && !this._wellInArea(focalWell, area)) { focalWell = null; @@ -65,19 +65,19 @@ var plateLayOutWidget = plateLayOutWidget || {}; selectedAreas = [this._wellToArea(focalWell)]; } return { - selectedAreas: selectedAreas, + selectedAreas: selectedAreas, focalWell: focalWell }; - }, + }, - sanitizeWell: function (well) { + sanitizeWell: function(well) { var newWell = {}; for (var i = 0; i < this.fieldList.length; i++) { var field = this.fieldList[i]; newWell[field.id] = field.parseValue(well[field.id]); } - return newWell; - }, + return newWell; + }, setData: function(data) { this.engine.derivative = $.extend(true, {}, data.derivative); diff --git a/src/js/overlay.js b/src/js/overlay.js index f448e5d..ac622ea 100755 --- a/src/js/overlay.js +++ b/src/js/overlay.js @@ -69,7 +69,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; if (this.emptyWellWithDefaultVal && this.disableAddDeleteWell) { var well = JSON.parse(JSON.stringify(this.defaultWell)); var defaultValue = this.emptyWellWithDefaultVal; - for (var key in defaultValue){ + for (var key in defaultValue) { if (key in well) { well[key] = defaultValue[key]; this._applyFieldData(key, defaultValue[key]); @@ -84,7 +84,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; hasWellUpdate = true; } } - if (hasWellUpdate){ + if (hasWellUpdate) { this.derivativeChange(); } @@ -97,8 +97,8 @@ var plateLayOutWidget = plateLayOutWidget || {}; copyCriteria: function() { if (this.allSelectedObjects) { - var wells = this._getSelectedWells(); - this.commonWell = this._getCommonFields(wells); + var wells = this._getSelectedWells(); + this.commonWell = this._getCommonFields(wells); } else { alert("Please select any well."); } diff --git a/src/js/plate-layout.js b/src/js/plate-layout.js index 398d286..2c2497a 100755 --- a/src/js/plate-layout.js +++ b/src/js/plate-layout.js @@ -1,331 +1,331 @@ $.widget("DNA.plateLayOut", { - plateLayOutWidget: {}, - - options: { - value: 0 - }, - - allTiles: [], // All tiles containes all thise circles in the canvas - - addressToLoc: function (layoutAddress) { - var m = /^([A-Z]+)(\d+)$/.exec(layoutAddress.trim().toUpperCase()) - if (m) { - var row_v = m[1]; - var col = parseInt(m[2]) - 1; - var row; - for (var i = 0; i < row_v.length; i++) { - var c = row_v.charCodeAt(i) - 65; - if (i) { - row += 1; - row *= 26; - row += c; - } else { - row = c; - } - } - return { - r: row, - c: col - }; + plateLayOutWidget: {}, + + options: { + value: 0 + }, + + allTiles: [], // All tiles containes all thise circles in the canvas + + addressToLoc: function(layoutAddress) { + var m = /^([A-Z]+)(\d+)$/.exec(layoutAddress.trim().toUpperCase()) + if (m) { + var row_v = m[1]; + var col = parseInt(m[2]) - 1; + var row; + for (var i = 0; i < row_v.length; i++) { + var c = row_v.charCodeAt(i) - 65; + if (i) { + row += 1; + row *= 26; + row += c; } else { - throw layoutAddress + " not a proper layout address"; + row = c; } - }, + } + return { + r: row, + c: col + }; + } else { + throw layoutAddress + " not a proper layout address"; + } + }, - locToIndex: function (loc, dimensions) { - if (!dimensions) { - dimensions = this.dimensions; - } - if (loc.r < 0) { - t - } - if (!(loc.r >= 0 && loc.r < dimensions.rows)) { - throw "Row index " + (loc.r + 1) + " invalid"; - } - if (!(loc.c >= 0 && loc.c < dimensions.cols)) { - throw "Column index " + (loc.c + 1) + " invalid"; - } - return loc.r * dimensions.cols + loc.c; - }, - - addressToIndex: function (layoutAddress, dimensions) { - var loc = this.addressToLoc(layoutAddress); - return this.locToIndex(loc, dimensions); - }, - - _rowKey: function (i) { - var c1 = i % 26; - var c2 = (i - c1) / 26; - var code = String.fromCharCode(65 + c1); - if (c2 > 0) { - code = String.fromCharCode(64 + c2) + code; - } - return code; - }, + locToIndex: function(loc, dimensions) { + if (!dimensions) { + dimensions = this.dimensions; + } + if (loc.r < 0) { + t + } + if (!(loc.r >= 0 && loc.r < dimensions.rows)) { + throw "Row index " + (loc.r + 1) + " invalid"; + } + if (!(loc.c >= 0 && loc.c < dimensions.cols)) { + throw "Column index " + (loc.c + 1) + " invalid"; + } + return loc.r * dimensions.cols + loc.c; + }, + + addressToIndex: function(layoutAddress, dimensions) { + var loc = this.addressToLoc(layoutAddress); + return this.locToIndex(loc, dimensions); + }, + + _rowKey: function(i) { + var c1 = i % 26; + var c2 = (i - c1) / 26; + var code = String.fromCharCode(65 + c1); + if (c2 > 0) { + code = String.fromCharCode(64 + c2) + code; + } + return code; + }, - indexToLoc: function (index, dimensions) { - if (!dimensions) { - dimensions = this.dimensions; - } + indexToLoc: function(index, dimensions) { + if (!dimensions) { + dimensions = this.dimensions; + } - if (index >= dimensions.rows * dimensions.cols) { - throw "Index too high: " + index.toString(10); - } - var loc = {}; - loc.c = index % dimensions.cols; - loc.r = (index - loc.c) / dimensions.cols; - - return loc; - }, - - locToAddress: function (loc) { - return this._rowKey(loc.r) + (loc.c + 1).toString(10); - }, - - indexToAddress: function (index, dimensions) { - var loc = this.indexToLoc(index, dimensions); - return this.locToAddress(loc); - }, - - getDimensions: function () { - return $.extend(true, {}, this.dimensions); - }, - - _create: function () { - var rows = parseInt(this.options.numRows || 8); - var cols = parseInt(this.options.numCols || 12); - this.dimensions = { - rows: rows, - cols: cols - }; - this.rowIndex = []; - for (var i = 0; i < rows; i++) { - this.rowIndex.push(this._rowKey(i)); - } + if (index >= dimensions.rows * dimensions.cols) { + throw "Index too high: " + index.toString(10); + } + var loc = {}; + loc.c = index % dimensions.cols; + loc.r = (index - loc.c) / dimensions.cols; + + return loc; + }, + + locToAddress: function(loc) { + return this._rowKey(loc.r) + (loc.c + 1).toString(10); + }, + + indexToAddress: function(index, dimensions) { + var loc = this.indexToLoc(index, dimensions); + return this.locToAddress(loc); + }, + + getDimensions: function() { + return $.extend(true, {}, this.dimensions); + }, + + _create: function() { + var rows = parseInt(this.options.numRows || 8); + var cols = parseInt(this.options.numCols || 12); + this.dimensions = { + rows: rows, + cols: cols + }; + this.rowIndex = []; + for (var i = 0; i < rows; i++) { + this.rowIndex.push(this._rowKey(i)); + } - this.target = (this.element[0].id) ? "#" + this.element[0].id : "." + this.element[0].className; + this.target = (this.element[0].id) ? "#" + this.element[0].id : "." + this.element[0].className; - // Import classes from other files.. Here we import it using extend and add it to this - // object. internally we add to widget.DNA.getPlates.prototype. - // Helpers are methods which return other methods and objects. - // add Objects to plateLayOutWidget and it will be added to this object. - // set read only well - if (this.options.readOnly) { - this.isReadOnly(true); - } + // Import classes from other files.. Here we import it using extend and add it to this + // object. internally we add to widget.DNA.getPlates.prototype. + // Helpers are methods which return other methods and objects. + // add Objects to plateLayOutWidget and it will be added to this object. + // set read only well + if (this.options.readOnly) { + this.isReadOnly(true); + } - for (var component in plateLayOutWidget) { - // Incase some properties has to initialize with data from options hash, - // we provide it sending this object. - $.extend(this, new plateLayOutWidget[component](this)); - } + for (var component in plateLayOutWidget) { + // Incase some properties has to initialize with data from options hash, + // we provide it sending this object. + $.extend(this, new plateLayOutWidget[component](this)); + } - this.imgSrc = this.options.imgSrc || "assets"; - - this._createInterface(); - - this._trigger("created", null, this); - - return this; - }, - - _init: function () { - // This is invoked when the user use the plugin after _create is called. - // The point is _create is invoked for the very first time and for all other - // times _init is used. - }, - - addData: function () { - alert("wow this is good"); - }, - - // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}} - getTextDerivative: function (wellsData) { - var textDerivative = {}; - var fieldMap = this.fieldMap; - for (var idx in wellsData) { - var textValWell = {}; - var textFieldIdWell = {}; - var curWellData = wellsData[idx]; - for (var fieldId in curWellData) { - if (fieldId in this.fieldMap) { - var field = this.fieldMap[fieldId]; - var textVal = field.parseText(curWellData[fieldId]); - textFieldIdWell[field.name] = textVal; - textValWell[fieldId] = textVal; - } else { - // do not convert if not a field (ex: layout_address) - textFieldIdWell[fieldId] = curWellData[fieldId]; - textValWell[fieldId] = curWellData[fieldId]; - } - } - textDerivative[idx] = { - textVal: textValWell, - textFieldVal: textFieldIdWell - }; + this.imgSrc = this.options.imgSrc || "assets"; + + this._createInterface(); + + this._trigger("created", null, this); + + return this; + }, + + _init: function() { + // This is invoked when the user use the plugin after _create is called. + // The point is _create is invoked for the very first time and for all other + // times _init is used. + }, + + addData: function() { + alert("wow this is good"); + }, + + // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}} + getTextDerivative: function(wellsData) { + var textDerivative = {}; + var fieldMap = this.fieldMap; + for (var idx in wellsData) { + var textValWell = {}; + var textFieldIdWell = {}; + var curWellData = wellsData[idx]; + for (var fieldId in curWellData) { + if (fieldId in this.fieldMap) { + var field = this.fieldMap[fieldId]; + var textVal = field.parseText(curWellData[fieldId]); + textFieldIdWell[field.name] = textVal; + textValWell[fieldId] = textVal; + } else { + // do not convert if not a field (ex: layout_address) + textFieldIdWell[fieldId] = curWellData[fieldId]; + textValWell[fieldId] = curWellData[fieldId]; } + } + textDerivative[idx] = { + textVal: textValWell, + textFieldVal: textFieldIdWell + }; + } - return textDerivative; - }, - - // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}} - getWellsDifferences: function (wellsData) { - return this.getDifferentWellsVals(wellsData); - }, - - setFieldsDisabled: function (flag) { - this.fieldList.forEach(function (field) { - field.disabled(flag); - }); - }, + return textDerivative; + }, + + // wellsData follows syntax: {0:{field1: val1, field2: val2}, 1:{field1: val1, field2: val2}} + getWellsDifferences: function(wellsData) { + return this.getDifferentWellsVals(wellsData); + }, + + setFieldsDisabled: function(flag) { + this.fieldList.forEach(function(field) { + field.disabled(flag); + }); + }, + + isReadOnly: function(flag) { + if (flag) { + this.readOnly = true; + } else { + this.readOnly = false; + } + this.readOnlyHandler(); + }, + + readOnlyHandler: function() { + if (this.readOnly) { + this.overLayButtonContainer.css("display", "none"); + $('.multiple-field-manage-delete-button').css("display", "none"); + this.setFieldsDisabled(true); + } else { + this.overLayButtonContainer.css("display", "flex"); + $('.multiple-field-manage-delete-button').css("display", "none"); + if (!this.disableAddDeleteWell) { + this.setFieldsDisabled(false); + } + } + }, + + disableAddDeleteWell: null, + // column_with_default_val will be used to determine empty wells, format: {field_name: default_val} + isDisableAddDeleteWell: function(flag, column_with_default_val) { + if (flag) { + this.disableAddDeleteWell = true; + this.addressAllowToEdit = this.getWellSetAddressWithData(); + // configure undo redo action + this.actionPointer = 0; + this.undoRedoArray = []; + this.undoRedoArray.push(this.createObject()); + if (column_with_default_val) { + this.emptyWellWithDefaultVal = column_with_default_val; + } + } else { + this.disableAddDeleteWell = false; + this.setFieldsDisabled(false); + this.emptyWellWithDefaultVal = null; + } + this._fabricEvents(); + }, - isReadOnly: function (flag) { - if (flag) { - this.readOnly = true; - } else { - this.readOnly = false; + getSelectedObject: function() { + var selectedAddress = []; + for (var i = 0; i < this.allSelectedObjects.length; i++) { + selectedAddress.push(this.allSelectedObjects[i].address); + } + var selectedObjects = {}; + var derivative = this.engine.derivative; + for (var index in derivative) { + var address = this.indexToAddress(index); + if (selectedAddress.indexOf(address) >= 0) { + var well = JSON.parse(JSON.stringify(derivative[index])); + well.colorIndex = this.engine.colorMap.get(Number(index)); + selectedObjects[address] = well; + } + } + return selectedObjects; + }, + + selectObjectInBottomTab: function() { + var selectedObjects = this.getSelectedObject(); + var selectedObjectAddress; + for (var prop in selectedObjects) { + if (!selectedObjectAddress) { + selectedObjectAddress = prop; + } else { + return; // scroll to matching group only if a single well has been selected + } + } + if (selectedObjects[selectedObjectAddress]) { + var colorIndex = selectedObjects[selectedObjectAddress].colorIndex; + var trs = document.querySelectorAll('table.plate-setup-bottom-table tr'); + for (var i = 1; i < trs.length; i++) { // start at 1 to skip the table headers + var tds = trs[i].children; + var isSelected = tds[0].querySelector('button').innerHTML === colorIndex.toString(); + for (var j = 1; j < tds.length; j++) { + if (isSelected) { + tds[j].style.background = '#22cb94'; + } else { + tds[j].style.background = '#ffffff'; + } } - this.readOnlyHandler(); - }, - - readOnlyHandler: function () { - if (this.readOnly) { - this.overLayButtonContainer.css("display", "none"); - $('.multiple-field-manage-delete-button').css("display", "none"); - this.setFieldsDisabled(true); - } else { - this.overLayButtonContainer.css("display", "flex"); - $('.multiple-field-manage-delete-button').css("display", "none"); - if (!this.disableAddDeleteWell) { - this.setFieldsDisabled(false); - } + if (isSelected) { + scrollTo(document.querySelector('.plate-setup-bottom-table-container'), tds[0].offsetTop, 300); } - }, - - disableAddDeleteWell: null, - // column_with_default_val will be used to determine empty wells, format: {field_name: default_val} - isDisableAddDeleteWell: function (flag, column_with_default_val) { - if (flag) { - this.disableAddDeleteWell = true; - this.addressAllowToEdit = this.getWellSetAddressWithData(); - // configure undo redo action - this.actionPointer = 0; - this.undoRedoArray = []; - this.undoRedoArray.push(this.createObject()); - if (column_with_default_val) { - this.emptyWellWithDefaultVal = column_with_default_val; - } + } + } + }, + + getSelectedIndex: function() { + return this.allSelectedObjects.map(function(selectedObj) { + return that.addressToIndex(selectedObj.address) + }); + }, + + getSelectedAddress: function() { + return this.allSelectedObjects.map(function(selectedObj) { + return selectedObj.address; + }); + }, + + setSelectedWell: function(addressList) { + var areas = []; + var minRow = 999; + var locMap = {}; + for (var id = 0; id < addressList.length; id++) { + var wellIdx = this.addressToIndex(addressList[id]); + var loc = this.indexToLoc(wellIdx); + areas.push({ + minCol: loc.c, + minRow: loc.r, + maxCol: loc.c, + maxRow: loc.r + }); + if (loc.r <= minRow) { + minRow = loc.r; + if (loc.r in locMap) { + locMap[loc.r].push(loc.c); } else { - this.disableAddDeleteWell = false; - this.setFieldsDisabled(false); - this.emptyWellWithDefaultVal = null; - } - this._fabricEvents(); - }, - - getSelectedObject: function () { - var selectedAddress = []; - for (var i = 0; i < this.allSelectedObjects.length; i++) { - selectedAddress.push(this.allSelectedObjects[i].address); + locMap[loc.r] = [loc.c]; } - var selectedObjects = {}; - var derivative = this.engine.derivative; - for (var index in derivative) { - var address = this.indexToAddress(index); - if (selectedAddress.indexOf(address) >= 0) { - var well = JSON.parse(JSON.stringify(derivative[index])); - well.colorIndex = this.engine.colorMap.get(Number(index)); - selectedObjects[address] = well; - } - } - return selectedObjects; - }, - - selectObjectInBottomTab: function () { - var selectedObjects = this.getSelectedObject(); - var selectedObjectAddress; - for (var prop in selectedObjects) { - if (!selectedObjectAddress) { - selectedObjectAddress = prop; - } else { - return; // scroll to matching group only if a single well has been selected - } - } - if (selectedObjects[selectedObjectAddress]) { - var colorIndex = selectedObjects[selectedObjectAddress].colorIndex; - var trs = document.querySelectorAll('table.plate-setup-bottom-table tr'); - for (var i = 1; i < trs.length; i++) { // start at 1 to skip the table headers - var tds = trs[i].children; - var isSelected = tds[0].querySelector('button').innerHTML === colorIndex.toString(); - for (var j = 1; j < tds.length; j++) { - if (isSelected) { - tds[j].style.background = '#22cb94'; - } else { - tds[j].style.background = '#ffffff'; - } - } - if (isSelected) { - scrollTo(document.querySelector('.plate-setup-bottom-table-container'), tds[0].offsetTop, 300); - } - } - } - }, - - getSelectedIndex: function () { - return this.allSelectedObjects.map(function (selectedObj) { - return that.addressToIndex(selectedObj.address) - }); - }, - - getSelectedAddress: function () { - return this.allSelectedObjects.map(function (selectedObj) { - return selectedObj.address; - }); - }, - - setSelectedWell: function (addressList) { - var areas = []; - var minRow = 999; - var locMap = {}; - for (var id = 0; id < addressList.length; id++) { - var wellIdx = this.addressToIndex(addressList[id]); - var loc = this.indexToLoc(wellIdx); - areas.push({ - minCol: loc.c, - minRow: loc.r, - maxCol: loc.c, - maxRow: loc.r - }); - if (loc.r <= minRow) { - minRow = loc.r; - if (loc.r in locMap) { - locMap[loc.r].push(loc.c); - } else { - locMap[loc.r] = [loc.c]; - } - } - } - var focalWell = { - row: minRow, - col: Math.min.apply(null, locMap[minRow]) - }; - - this.setSelection(areas, focalWell); - this.decideSelectedFields(); - this.mainFabricCanvas.renderAll(); + } } + var focalWell = { + row: minRow, + col: Math.min.apply(null, locMap[minRow]) + }; + + this.setSelection(areas, focalWell); + this.decideSelectedFields(); + this.mainFabricCanvas.renderAll(); + } }); // https://stackoverflow.com/questions/17733076/smooth-scroll-anchor-links-without-jquery function scrollTo(element, to, duration) { - if (duration <= 0) return; - var difference = to - element.scrollTop; - var perTick = difference / duration * 10; - setTimeout(function () { - element.scrollTop = element.scrollTop + perTick; - if (element.scrollTop === to) return; - scrollTo(element, to, duration - 10); - }, 10); + if (duration <= 0) return; + var difference = to - element.scrollTop; + var perTick = difference / duration * 10; + setTimeout(function() { + element.scrollTop = element.scrollTop + perTick; + if (element.scrollTop === to) return; + scrollTo(element, to, duration - 10); + }, 10); } \ No newline at end of file diff --git a/src/js/preset.js b/src/js/preset.js index 218b900..c5968af 100755 --- a/src/js/preset.js +++ b/src/js/preset.js @@ -40,14 +40,14 @@ var plateLayOutWidget = plateLayOutWidget || {}; _clearPresetSelection: function() { for (var j = 0; j < this.presets.length; j++) { - var p = this.presets[j]; + var p = this.presets[j]; p.removeClass("plate-setup-prest-tab-selected") - .addClass("plate-setup-prest-tab"); + .addClass("plate-setup-prest-tab"); } }, - _selectPreset: function (preset) { - this.setCheckboxes(preset.data("preset")); + _selectPreset: function(preset) { + this.setCheckboxes(preset.data("preset")); preset.removeClass("plate-setup-prest-tab") .addClass("plate-setup-prest-tab-selected"); }, diff --git a/src/js/tabs.js b/src/js/tabs.js index 8ff9545..7a8482e 100755 --- a/src/js/tabs.js +++ b/src/js/tabs.js @@ -30,7 +30,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; var tabData = this.options.attributes.tabs; var that = this; - tabData.forEach(function (tab, tabIndex) { + tabData.forEach(function(tab, tabIndex) { that.allTabs[tabIndex] = that._createElement("<div></div>").addClass("plate-setup-tab"); $(that.allTabs[tabIndex]).data("index", tabIndex) .text(tab.name); @@ -40,7 +40,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; }); $(that.tabHead).append(that.allTabs[tabIndex]); - }); + }); this.tabDataContainer = this._createElement("<div></div>").addClass("plate-setup-tab-data-container"); $(this.tabContainer).append(this.tabDataContainer); diff --git a/src/js/undo-redo-manager.js b/src/js/undo-redo-manager.js index e6a226c..c26c954 100755 --- a/src/js/undo-redo-manager.js +++ b/src/js/undo-redo-manager.js @@ -13,7 +13,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; addToUndoRedo: function(data) { if (this.actionPointer != null) { - var i = this.actionPointer + 1; + var i = this.actionPointer + 1; if (i < this.undoRedoArray.length) { this.undoRedoArray.splice(i, this.undoRedoArray.length - i); } @@ -39,40 +39,40 @@ var plateLayOutWidget = plateLayOutWidget || {}; } }; - this.undoRedoArray = []; - this.actionPointer = null; + this.undoRedoArray = []; + this.actionPointer = null; this.undoRedoArray.push($.extend({}, data)); }, undo: function() { console.log("undo"); - return this.shiftUndoRedo(-1); + return this.shiftUndoRedo(-1); }, redo: function() { console.log("redo"); - return this.shiftUndoRedo(1); - }, + return this.shiftUndoRedo(1); + }, - shiftUndoRedo: function (pointerDiff) { + shiftUndoRedo: function(pointerDiff) { var pointer = this.actionPointer; if (pointer == null) { - pointer = this.undoRedoArray.length - 1; + pointer = this.undoRedoArray.length - 1; } - pointer += pointerDiff; - return this.setUndoRedo(pointer); - }, + pointer += pointerDiff; + return this.setUndoRedo(pointer); + }, - setUndoRedo: function (pointer) { + setUndoRedo: function(pointer) { if (pointer < 0) { - return false; + return false; } if (pointer >= this.undoRedoArray.length) { - return false; + return false; } - this.undoRedoActive = true; + this.undoRedoActive = true; this.setData(this.undoRedoArray[pointer]); - this.actionPointer = pointer; + this.actionPointer = pointer; this.undoRedoActive = false; this.derivativeChange(); return true; diff --git a/src/js/well-area.js b/src/js/well-area.js index 364a649..e030a53 100644 --- a/src/js/well-area.js +++ b/src/js/well-area.js @@ -16,8 +16,8 @@ var plateLayOutWidget = plateLayOutWidget || {}; for (var c = area.minCol; c <= area.maxCol; c++) { var tile = that.allTiles[c + cols * r]; if (tiles.indexOf(tile) < 0) { - if (that.disableAddDeleteWell){ - if(that.addressAllowToEdit.indexOf(tile.address) >= 0){ + if (that.disableAddDeleteWell) { + if (that.addressAllowToEdit.indexOf(tile.address) >= 0) { tiles.push(tile); } } else { @@ -155,8 +155,8 @@ var plateLayOutWidget = plateLayOutWidget || {}; var cols = this.dimensions.cols; var rows = this.dimensions.rows; - var w = this.sizes.spacing; - var m = this.sizes.label_spacing; + var w = this.sizes.spacing; + var m = this.sizes.label_spacing; var x = (coord.x - m) / w; var y = (coord.y - m) / w; @@ -172,12 +172,12 @@ var plateLayOutWidget = plateLayOutWidget || {}; _wellToCoords: function(well, center) { //Convert a well to a coordinate - var w = this.sizes.spacing; - var m = this.sizes.label_spacing; + var w = this.sizes.spacing; + var m = this.sizes.label_spacing; var x = well.col * w + m; var y = well.row * w + m; if (center) { - var hw = w/2; + var hw = w / 2; x = x + hw; y = y + hw; } @@ -193,8 +193,8 @@ var plateLayOutWidget = plateLayOutWidget || {}; var rows = area.maxRow - area.minRow + 1; var cols = area.maxCol - area.minCol + 1; - var w = this.sizes.spacing; - var m = this.sizes.label_spacing; + var w = this.sizes.spacing; + var m = this.sizes.label_spacing; return { top: area.minRow * w + m, @@ -209,8 +209,8 @@ var plateLayOutWidget = plateLayOutWidget || {}; var rows = this.dimensions.rows; var cols = this.dimensions.cols; - var w = this.sizes.spacing; - var m = this.sizes.label_spacing; + var w = this.sizes.spacing; + var m = this.sizes.label_spacing; var left = (rect.left - m) / w; var top = (rect.top - m) / w; From 211f879a05957fd3ea3e0a7d87f67c6b37aa6b73 Mon Sep 17 00:00:00 2001 From: Jeremy Gore <jeremy.gore@tessella.com> Date: Fri, 5 Apr 2019 11:57:02 -0400 Subject: [PATCH 07/10] Document createObject --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index ff51d22..3eddc3e 100644 --- a/README.md +++ b/README.md @@ -233,6 +233,12 @@ This function may be called at any time to load data. Well data should be passed } ``` +## createObject() +Calling this function will return the current state of the plate-map, in the form as passed into `getPlates`. +```js +$("#my-plate-layout").plateLayOut("createObject") +``` + ## isReadOnly() This function will disable editing of the plates, set `flag` to true for read only mode and set `flag` to false to disable read only mode ```js From 18781f536286882cdbeb5c8aa9176413d6c4124f Mon Sep 17 00:00:00 2001 From: Jeremy Gore <jeremy.gore@tessella.com> Date: Fri, 5 Apr 2019 11:54:53 -0400 Subject: [PATCH 08/10] Work with select2 v4 --- gulpfile.js | 21 ++---- package-lock.json | 22 +++++-- package.json | 2 +- src/js/add-tab-data.js | 6 +- src/js/create-field.js | 141 ++++++++++++++++------------------------- 5 files changed, 80 insertions(+), 112 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 0025657..ade0fa5 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -21,19 +21,15 @@ const PATH = { dependencies: { css: [ 'node_modules/bootstrap/dist/css/bootstrap.css', - 'node_modules/select2/select2.css' + 'node_modules/select2/dist/css/select2.css' ], js: [ 'node_modules/jquery/dist/jquery.js', 'node_modules/jquery-ui-dist/jquery-ui.js', 'node_modules/bootstrap/dist/js/bootstrap.js', - 'node_modules/select2/select2.js', + 'node_modules/select2/dist/js/select2.js', 'node_modules/fabric/dist/fabric.js', 'node_modules/clipboard/dist/clipboard.js' - ], - img: [ - 'node_modules/select2/*.png', - 'node_modules/select2/*.gif' ] }, }, @@ -56,7 +52,7 @@ const PATH = { } }; -let config = {source: {css: '', js: '', img: '', html: '', json: ''}, destination: {css: '', js: '', root: ''}}; +let config = {source: {css: '', js: '', html: '', json: ''}, destination: {css: '', js: '', root: ''}}; function concat_minify_css(name, source, destination) { return gulp.src(source, { sourcemaps: true }) @@ -79,7 +75,6 @@ function concat_uglify_js(name, source, destination) { function config_env(env) { config.source.css = PATH.source.dependencies.css.concat(PATH.source.app.css); config.source.js = PATH.source.dependencies.js.concat(PATH.source.app.js); - config.source.img = PATH.source.dependencies.img; config.source.html = PATH.source.app.html; config.destination.css = PATH.destination[env].css; config.destination.js = PATH.destination[env].js; @@ -123,12 +118,6 @@ gulp.task('copy.src', () => { return mergeStream(css, js); }); -// Copy images of Select2 (v3.5.1) dependency to 'dist/prod/css' -gulp.task('copy.img', () => { - return gulp.src(config.source.img) - .pipe(gulp.dest(config.destination.css)); -}); - gulp.task('inject.prod', () => { return gulp.src(config.source.html) .pipe(inject(gulp.src([`${config.destination.css}/*.min.css`, `${config.destination.js}/*.min.js`], {read: false}), @@ -176,11 +165,11 @@ gulp.task('server.prod', async () => { gulp.task('build.dist', gulp.series('config.pack', 'clean', 'css', 'js')); -gulp.task('build.dev', gulp.series('config.dev', 'clean', 'copy.src', 'copy.img', 'inject.dev')); +gulp.task('build.dev', gulp.series('config.dev', 'clean', 'copy.src', 'inject.dev')); gulp.task('serve.dev', gulp.series('build.dev', 'server.dev')); -gulp.task('build.prod', gulp.series('config.prod', 'clean', 'css', 'js', 'copy.img', 'inject.prod')); +gulp.task('build.prod', gulp.series('config.prod', 'clean', 'css', 'js', 'inject.prod')); gulp.task('serve.prod', gulp.series('build.prod', 'server.prod')); diff --git a/package-lock.json b/package-lock.json index f3372bb..ca6eda6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "plate-map", - "version": "1.0.1", + "version": "1.0.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -53,6 +53,11 @@ "uri-js": "^4.2.2" } }, + "almond": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/almond/-/almond-0.3.3.tgz", + "integrity": "sha1-oOfJWsdiTWQXtElLHmi/9pMWiiA=" + }, "ansi-colors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", @@ -3708,6 +3713,11 @@ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz", "integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==" }, + "jquery-mousewheel": { + "version": "3.1.13", + "resolved": "https://registry.npmjs.org/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz", + "integrity": "sha1-BvAzXxbjU6aV5yBr9QUDy1I6buU=" + }, "jquery-ui-dist": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/jquery-ui-dist/-/jquery-ui-dist-1.12.1.tgz", @@ -5322,9 +5332,13 @@ "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=" }, "select2": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/select2/-/select2-3.5.1.tgz", - "integrity": "sha1-8oGUibvGX9bTKL5yu+K5XdfofP4=" + "version": "4.0.6-rc.1", + "resolved": "https://registry.npmjs.org/select2/-/select2-4.0.6-rc.1.tgz", + "integrity": "sha1-qmwwOKfw8ukf+t448KIcFeGBMnY=", + "requires": { + "almond": "~0.3.1", + "jquery-mousewheel": "~3.1.13" + } }, "semver": { "version": "5.6.0", diff --git a/package.json b/package.json index 4f0efc3..298dc7c 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "jquery": "^3.3.1", "jquery-ui-dist": "^1.12.1", "popper.js": "^1.14.7", - "select2": "^3.5.1" + "select2": "^4.0.6-rc.1" }, "devDependencies": { "browser-sync": "^2.26.3", diff --git a/src/js/add-tab-data.js b/src/js/add-tab-data.js index c08e86a..dc2dd82 100755 --- a/src/js/add-tab-data.js +++ b/src/js/add-tab-data.js @@ -226,11 +226,9 @@ var plateLayOutWidget = plateLayOutWidget || {}; }); field.getValue = function() { - var v = field.input.select2('data'); + var v = field.input.val(); if (v.length) { - return v.map(function(i) { - return i.id; - }); + return v; } return null; }; diff --git a/src/js/create-field.js b/src/js/create-field.js index 249cc8f..2e4ed37 100755 --- a/src/js/create-field.js +++ b/src/js/create-field.js @@ -3,7 +3,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; (function($, fabric) { plateLayOutWidget.createField = function() { - // It create those fields in the tab , there is 4 types of them. + // It creates those fields in the tab , there is 4 types of them. return { _createField: function(field) { @@ -90,17 +90,18 @@ var plateLayOutWidget = plateLayOutWidget || {}; placeholder: "select", minimumResultsForSearch: 10 }; + var data_specified = false; if (config.options) { opts.data = config.options; - } else if (config.query) { - var query = config.query; - if (config.delay) { - query = this._debounce(config.delay, query); - } - opts.query = query; - } else { - throw "Must specify data or query"; + data_specified = true; + } + if (config.ajax) { + opts.ajax = ajax; + data_specified = true; + } + if (!data_specified) { + throw "Must specify data or ajax"; } return opts; }, @@ -108,7 +109,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; _createSelectField: function(field) { var id = field.id; var that = this; - var input = this._createElement("<input/>").attr("id", id) + var input = this._createElement("<select/>").attr("id", id) .addClass("plate-setup-tab-select-field"); field.root.find(".plate-setup-tab-field-container").append(input); @@ -143,21 +144,12 @@ var plateLayOutWidget = plateLayOutWidget || {}; }; field.getValue = function() { - var v = input.select2('data'); - return v ? v.id : null; + return input.val(); }; field.setValue = function(v) { - if (v) { - v = optMap[v]; - } - input.select2('data', v); - }; - - field.setOpts = function(v) { - input.select2('data', {}); - opts.data = v || []; - input.select2(opts); + input.val(v); + input.trigger("change.select2") }; field.getText = function(v) { @@ -193,7 +185,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; _createMultiSelectField: function(field) { var id = field.id; var that = this; - var input = this._createElement("<input/>").attr("id", id) + var input = this._createElement("<select/>").attr("id", id) .addClass("plate-setup-tab-multiselect-field"); input.attr("multiple", "multiple"); @@ -229,36 +221,18 @@ var plateLayOutWidget = plateLayOutWidget || {}; return v; }; - field.setOpts = function(v) { - var allOpts = field.data.options; - var selectedVal = []; - for (var id in allOpts) { - var curOpts = allOpts[id]; - if (v.indexOf(curOpts["id"]) >= 0) { - selectedVal.push(curOpts); - } - } - - opts.data = selectedVal; - input.select2(opts); - }; - field.getValue = function() { - var v = input.select2('data'); + var v = input.val(); if (v.length) { - return v.map(function(i) { - return i.id; - }); + return v; } return null; }; field.setValue = function(v) { v = v || []; - v = v.map(function(i) { - return optMap[i]; - }); - input.select2('data', v); + input.val(v); + input.trigger("change.select2"); }; field.getText = function(v) { @@ -306,11 +280,12 @@ var plateLayOutWidget = plateLayOutWidget || {}; return v; }; - input.on("change", function(e, generated) { - var added = e.added; - var removed = e.removed; - //field.onChange(); - field.multiOnChange(added, removed); + input.on("select2:select", function (e) { + field.multiOnChange(e.params.data, null); + }); + + input.on("select2:unselect", function (e) { + field.multiOnChange(null, e.params.data); }); field.input = input; @@ -355,7 +330,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; unitText.text(defaultUnit); field.root.find(".plate-setup-tab-field-container").append(unitText); } else { - unitInput = this._createElement("<input/>").attr("id", id) + unitInput = this._createElement("<select/>").attr("id", id) .addClass("plate-setup-tab-label-select-field"); field.root.find(".plate-setup-tab-field-container").append(unitInput); @@ -367,7 +342,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; text: unit }; if (unit == defaultUnit) { - selected = o; + selected = unit; } return o; }); @@ -379,7 +354,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; }; unitInput.select2(opts); - unitInput.select2("data", selected); + unitInput.val(selected); } } @@ -404,7 +379,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; text: curUnit }; if (curUnit == field.defaultUnit) { - selected = cleanUnit; + selected = curUnit; } return cleanUnit; }); @@ -415,8 +390,11 @@ var plateLayOutWidget = plateLayOutWidget || {}; allowClear: false, minimumResultsForSearch: 10 }; + unitInput.select2("destroy"); + unitInput.val(null); + unitInput.empty(); unitInput.select2(newOpts); - unitInput.select2("data", selected); + unitInput.val(selected); }; field.parseValue = function(value) { @@ -546,13 +524,8 @@ var plateLayOutWidget = plateLayOutWidget || {}; field.setUnit = function(unit) { if (unitInput) { unit = unit || field.defaultUnit; - if (unit != null) { - unit = { - id: unit, - text: unit - }; - } - unitInput.select2("data", unit); + unitInput.val(unit); + unitInput.trigger("change.select2"); } }; @@ -619,7 +592,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; _createBooleanField: function(field) { var id = field.id; var that = this; - var input = this._createElement("<input/>").attr("id", id) + var input = this._createElement("<select/>").attr("id", id) .addClass("plate-setup-tab-select-field"); that.defaultWell[id] = null; @@ -636,14 +609,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; data: [tval, fval], placeholder: "select", allowClear: true, - minimumResultsForSearch: -1, - initSelection: function(element, callback) { - var v = element.val(); - callback({ - id: v, - text: v - }); - } + minimumResultsForSearch: -1 }; input.select2(opts); @@ -683,13 +649,14 @@ var plateLayOutWidget = plateLayOutWidget || {}; field.setValue = function(v) { if (v == true || v == "true") { - v = tval; + v = "true"; } else if (v == false || v == "false") { - v = fval; + v = "false"; } else { v = null; } - input.select2('data', v); + input.val(v); + input.trigger("change.select2"); }; field.getText = function(v) { @@ -720,17 +687,13 @@ var plateLayOutWidget = plateLayOutWidget || {}; var fieldContainer1 = that._createElement("<div></div>").addClass("plate-setup-tab-field-container-singleSelect"); field.root.find(".plate-setup-tab-field-right-side").append(nameContainer1, fieldContainer1); - field.singleSelect = this._createElement("<input/>").attr("id", field.id + "SingleSelect") + field.singleSelect = this._createElement("<select/>").attr("id", field.id + "SingleSelect") .addClass("plate-setup-tab-multiplex-single-select-field"); field.singleSelect.appendTo(fieldContainer1); field.singleSelectValue = function() { - var v = field.singleSelect.select2("data"); - if (v != null) { - v = v.id; - } - return v; + return field.singleSelect.val(); }; var setSingleSelectOptions = function(v, selected_v) { @@ -739,18 +702,24 @@ var plateLayOutWidget = plateLayOutWidget || {}; placeholder: "select", minimumResultsForSearch: 10, data: v || [] - } + }; if (!selected_v) { if (opts.data.length) { - selected_v = opts.data[0]; + selected_v = opts.data[0].id; } else { selected_v = null; } } - field.singleSelect.select2('data', []); + if (field.singleSelect.hasClass("select2-hidden-accessible")) { + field.singleSelect.select2("destroy"); + } + field.singleSelect.val(null); + field.singleSelect.empty(); field.singleSelect.select2(opts); - field.singleSelect.select2('data', selected_v); + field.singleSelect.val(selected_v); field.singleSelect.prop("disabled", opts.data.length == 0); + field.singleSelect.trigger("change.select2"); + field.singleSelect.on("change.select2", singleSelectChange); }; var singleSelectChange = function() { @@ -783,8 +752,6 @@ var plateLayOutWidget = plateLayOutWidget || {}; setSingleSelectOptions([]); - field.singleSelect.on("change", singleSelectChange); - field._changeMultiFieldValue = function(added, removed) { var newSubFieldValue = {}; for (var subFieldName in field.data.multiplexFields) { @@ -971,7 +938,7 @@ var plateLayOutWidget = plateLayOutWidget || {}; }); }); // set the newest selected to be the current obj - curOpt = selectList[v.length - 1]; + curOpt = selectList[v.length - 1].id; } field.detailData = newMultiplexVal; From bb2c7a5e4f6f328c002894cacd55191153cd67d5 Mon Sep 17 00:00:00 2001 From: Jeremy Gore <jeremy.gore@tessella.com> Date: Fri, 5 Apr 2019 13:46:06 -0400 Subject: [PATCH 09/10] Prevent select2 v4.0.6rc1 from opening dropdown on unselect --- src/js/create-field.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/js/create-field.js b/src/js/create-field.js index 2e4ed37..2b174e9 100755 --- a/src/js/create-field.js +++ b/src/js/create-field.js @@ -179,6 +179,12 @@ var plateLayOutWidget = plateLayOutWidget || {}; field.onChange(); }); + + input.on('select2:unselect', function (evt) { + // Prevent select2 v4.0.6rc1 opening dropdown on unselect + input.one('select2:opening', function(e) { e.preventDefault(); }); + }); + field.input = input; }, @@ -286,6 +292,8 @@ var plateLayOutWidget = plateLayOutWidget || {}; input.on("select2:unselect", function (e) { field.multiOnChange(null, e.params.data); + // Prevent select2 v4.0.6rc1 opening dropdown on unselect + input.one('select2:opening', function(e) { e.preventDefault(); }); }); field.input = input; @@ -672,6 +680,12 @@ var plateLayOutWidget = plateLayOutWidget || {}; field.onChange(); }); + + input.on('select2:unselect', function (evt) { + // Prevent select2 v4.0.6rc1 opening dropdown on unselect + input.one('select2:opening', function(e) { e.preventDefault(); }); + }); + field.input = input; }, From 8ac7ca952ff5be813d0272b1c5309516d012eccd Mon Sep 17 00:00:00 2001 From: Jeremy Gore <jeremy.gore@tessella.com> Date: Fri, 5 Apr 2019 14:02:55 -0400 Subject: [PATCH 10/10] Version 1.0.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 298dc7c..30ecb6d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plate-map", - "version": "1.0.2", + "version": "1.0.3", "description": "JavaScript Plate Layout is an open source tool developed collaboratively by [Chai Biotechnologies](www.chaibio.com) and [New England Biolabs](www.neb.com) for visualizing and editing the layout of scientific assay plates.", "scripts": { "build.dist": "gulp build.dist",